| // Copyright 2012 Google Inc. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package com.google.enterprise.adaptor.sharepoint; |
| |
| import com.google.enterprise.adaptor.AbstractAdaptor; |
| import com.google.enterprise.adaptor.AdaptorContext; |
| import com.google.enterprise.adaptor.Config; |
| import com.google.enterprise.adaptor.DocId; |
| import com.google.enterprise.adaptor.DocIdEncoder; |
| import com.google.enterprise.adaptor.DocIdPusher; |
| import com.google.enterprise.adaptor.IOHelper; |
| import com.google.enterprise.adaptor.Request; |
| import com.google.enterprise.adaptor.Response; |
| |
| import org.apache.axis2.AxisFault; |
| import org.apache.axis2.client.Options; |
| import org.apache.axis2.transport.http.HTTPConstants; |
| import org.apache.axis2.transport.http.HttpTransportProperties; |
| import org.apache.commons.httpclient.HttpClient; |
| import org.apache.commons.httpclient.HttpStatus; |
| import org.apache.commons.httpclient.Credentials; |
| import org.apache.commons.httpclient.UsernamePasswordCredentials; |
| import org.apache.commons.httpclient.auth.AuthScope; |
| import org.apache.commons.httpclient.methods.GetMethod; |
| |
| import java.io.*; |
| import java.net.URI; |
| import java.net.URISyntaxException; |
| import java.util.Arrays; |
| import java.util.concurrent.*; |
| |
| import javax.xml.stream.XMLInputFactory; |
| import javax.xml.stream.XMLStreamReader; |
| |
| /** |
| * SharePoint Adaptor for the GSA. |
| */ |
| public class SharePointAdaptor extends AbstractAdaptor { |
| private final ConcurrentMap<String, SiteDataClient> clients |
| = new ConcurrentSkipListMap<String, SiteDataClient>(); |
| private final XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory(); |
| private final DocId virtualServerDocId = new DocId(""); |
| private AdaptorContext context; |
| |
| // Configuration-provided values. |
| private String virtualServer; |
| private String username; |
| private String password; |
| |
| @Override |
| public void initConfig(Config config) { |
| config.addKey("sharepoint.server", null); |
| config.addKey("sharepoint.username", null); |
| config.addKey("sharepoint.password", null); |
| } |
| |
| @Override |
| public void init(AdaptorContext context) { |
| this.context = context; |
| Config config = context.getConfig(); |
| virtualServer = config.getValue("sharepoint.server"); |
| username = config.getValue("sharepoint.username"); |
| password = config.getValue("sharepoint.password"); |
| } |
| |
| @Override |
| public void getDocContent(Request request, Response response) |
| throws IOException { |
| try { |
| DocId id = request.getDocId(); |
| SiteDataClient virtualServerClient = getSiteDataClient(virtualServer); |
| if (id.equals(virtualServerDocId)) { |
| virtualServerClient.getVirtualServerDocContent(request, response); |
| } else { |
| SiteDataClient client |
| = virtualServerClient.getClientForUrl(id.getUniqueId()); |
| client.getDocContent(request, response); |
| } |
| } catch (RuntimeException ex) { |
| throw ex; |
| } catch (IOException ex) { |
| throw ex; |
| } catch (Exception ex) { |
| throw new IOException(ex); |
| } |
| } |
| |
| @Override |
| public void getDocIds(DocIdPusher pusher) throws InterruptedException { |
| pusher.pushDocIds(Arrays.asList(virtualServerDocId)); |
| } |
| |
| private SiteDataClient getSiteDataClient(String site) throws AxisFault { |
| SiteDataClient client = clients.get(site); |
| if (client == null) { |
| client = new SiteDataClient(site); |
| clients.putIfAbsent(site, client); |
| client = clients.get(site); |
| } |
| return client; |
| } |
| |
| public static void main(String[] args) throws Exception { |
| if (false) { |
| final String logPackage = "org.apache.commons.logging."; |
| System.setProperty(logPackage + "Log", logPackage + "impl.SimpleLog"); |
| System.setProperty(logPackage + "simplelog.log.httpclient.wire", "debug"); |
| System.setProperty( |
| logPackage + "simplelog.log.org.apache.commons.httpclient", "debug"); |
| } |
| AbstractAdaptor.main(new SharePointAdaptor(), args); |
| } |
| |
| private class SiteDataClient { |
| private static final boolean DEBUG = false; |
| private static final String XMLNS |
| = "http://schemas.microsoft.com/sharepoint/soap/"; |
| |
| private final SiteDataStub stub; |
| private final String siteUrl; |
| |
| public SiteDataClient(String site) throws AxisFault { |
| if (!site.endsWith("/")) { |
| // Always end with a '/' for a cannonical form. |
| site = site + "/"; |
| } |
| this.siteUrl = site; |
| this.stub = new SiteDataStub(site + "_vti_bin/SiteData.asmx"); |
| HttpTransportProperties.Authenticator auth |
| = new HttpTransportProperties.Authenticator(); |
| auth.setUsername(username); |
| auth.setPassword(password); |
| auth.setPreemptiveAuthentication(true); |
| Options options = stub._getServiceClient().getOptions(); |
| options.setProperty(HTTPConstants.AUTHENTICATE, auth); |
| options.setProperty(HTTPConstants.REUSE_HTTP_CLIENT, true); |
| } |
| |
| private void getDocContent(Request request, Response response) |
| throws Exception { |
| SiteDataStub.GetURLSegments urlRequest |
| = new SiteDataStub.GetURLSegments(); |
| urlRequest.setStrURL(request.getDocId().getUniqueId()); |
| SiteDataStub.GetURLSegmentsResponse urlResponse |
| = stub.getURLSegments(urlRequest); |
| if (!urlResponse.getGetURLSegmentsResult()) { |
| response.respondNotFound(); |
| return; |
| } |
| if (urlResponse.getStrWebID() != null) { |
| getSiteDocContent(request, response, urlResponse.getStrWebID()); |
| } else if (urlResponse.getStrItemID() != null) { |
| getListItemDocContent(request, response, urlResponse.getStrListID(), |
| urlResponse.getStrItemID()); |
| } else if (urlResponse.getStrListID() != null) { |
| getListDocContent(request, response, urlResponse.getStrListID()); |
| } else if (urlResponse.getStrBucketID() != null) { |
| response.respondNotFound(); |
| } else { |
| // Assume it is a top-level site. |
| getSiteDocContent(request, response, urlResponse.getStrWebID()); |
| } |
| } |
| |
| public void callChangesContentDatabase() throws Exception { |
| System.out.println(" ContentDatabase Changes"); |
| SiteDataStub.GetChanges request = new SiteDataStub.GetChanges(); |
| request.setObjectType(SiteDataStub.ObjectType.ContentDatabase); |
| request.setContentDatabaseId("{4fb7dea1-2912-4927-9eda-1ea2f0977cf8}"); |
| request.setLastChangeId( |
| "1;0;4fb7dea1-2912-4927-9eda-1ea2f0977cf8;634704678460030000;261"); |
| //request.setCurrentChangeId(""); |
| request.setTimeout(2); |
| SiteDataStub.GetChangesResponse response = stub.getChanges(request); |
| System.out.println(response.getMoreChanges()); |
| System.out.println(response.getCurrentChangeId()); |
| System.out.println(response.getLastChangeId()); |
| System.out.println(response.getGetChangesResult()); |
| } |
| |
| private String encodeUrl(String url) { |
| if (url.toLowerCase().startsWith("https://") |
| || url.toLowerCase().startsWith("http://")) { |
| // Leave as-is. |
| } else if (!url.startsWith("/")) { |
| url = siteUrl + url; |
| } else { |
| // Rip off everthing after the third slash (including the slash). |
| // Get http://example.com from http://example.com/some/folder. |
| String[] parts = siteUrl.split("/", 4); |
| url = parts[0] + "//" + parts[2] + url; |
| } |
| URI uri = context.getDocIdEncoder().encodeDocId(new DocId(url)); |
| return uri.toASCIIString(); |
| } |
| |
| private String liUrl(String url) { |
| // TODO(ejona): Fix raw string concatenation. |
| return "<li><a href=\"" + encodeUrl(url) + "\">" + url + "</a></li>"; |
| } |
| |
| private void getVirtualServerDocContent(Request request, Response response) |
| throws Exception { |
| SiteDataStub.VirtualServer vs = getContentVirtualServer(); |
| response.setContentType("text/html"); |
| Writer writer = new OutputStreamWriter(response.getOutputStream()); |
| writer.write("<!DOCTYPE html>\n" |
| + "<html><head>" |
| + "<title>VirtualServer " + vs.getMetadata().getURL() + "</title>" |
| + "</head>" |
| + "<body>" |
| + "<h1>VirtualServer " + vs.getMetadata().getURL() + "</h1>" |
| + "<p>Sites</p>" |
| + "<ul>"); |
| if (vs.getContentDatabases() != null) { |
| DocIdEncoder encoder = context.getDocIdEncoder(); |
| for (SiteDataStub.ContentDatabase_type0 cd_t0 |
| : vs.getContentDatabases().getContentDatabase()) { |
| SiteDataStub.ContentDatabase cd |
| = getContentContentDatabase(cd_t0.getID()); |
| if (cd.getSites() != null && cd.getSites().getSite() != null) { |
| for (SiteDataStub.Site_type0 site : cd.getSites().getSite()) { |
| writer.write(liUrl(site.getURL())); |
| } |
| } |
| } |
| } |
| writer.write("</ul></body></html>"); |
| writer.flush(); |
| } |
| |
| private void getSiteDocContent(Request request, Response response, |
| String id) throws Exception { |
| SiteDataStub.Web w = getContentWeb(id); |
| response.setContentType("text/html"); |
| Writer writer = new OutputStreamWriter(response.getOutputStream()); |
| writer.write("<!DOCTYPE html>\n" |
| + "<html><head>" |
| + "<title>Site " + w.getMetadata().getTitle() + "</title>" |
| + "</head>" |
| + "<body>" |
| + "<h1>Site " + w.getMetadata().getTitle() + "</h1>"); |
| |
| // TODO: w.getMetadata().getNoIndex() |
| DocIdEncoder encoder = context.getDocIdEncoder(); |
| if (w.getWebs() != null && w.getWebs().getWeb() != null) { |
| writer.write("<p>Sites</p><ul>"); |
| for (SiteDataStub.Web_type0 web : w.getWebs().getWeb()) { |
| writer.write(liUrl(web.getURL())); |
| } |
| writer.write("</ul>"); |
| } |
| if (w.getLists() != null && w.getLists().getList() != null) { |
| writer.write("<p>Lists</p><ul>"); |
| for (SiteDataStub.List_type0 list : w.getLists().getList()) { |
| writer.write(liUrl(list.getDefaultViewUrl())); |
| } |
| writer.write("</ul>"); |
| } |
| if (w.getFPFolder() != null) { |
| getFolderDataDocContent(writer, w.getFPFolder()); |
| } |
| writer.write("</body></html>"); |
| writer.flush(); |
| } |
| |
| private void getListDocContent(Request request, Response response, |
| String id) throws Exception { |
| SiteDataStub.List l = getContentList(id); |
| response.setContentType("text/html"); |
| Writer writer = new OutputStreamWriter(response.getOutputStream()); |
| writer.write("<!DOCTYPE html>\n" |
| + "<html><head>" |
| + "<title>List " + l.getMetadata().getTitle() + "</title>" |
| + "</head>" |
| + "<body>" |
| + "<h1>List " + l.getMetadata().getTitle() + "</h1>"); |
| if ("DocumentLibrary".equals(l.getMetadata().getBaseType().getValue())) { |
| SiteDataStub.FPFolder f |
| = getContentFolder(l.getMetadata().getRootFolder()); |
| getFolderDataDocContent(writer, f.getFPFolder()); |
| } else { |
| writer.write("<p>List Items</p><ul>"); |
| for (int i = 0; i < l.getMetadata().getItemCount(); i++) { |
| // TODO: determine URLs to provide. |
| } |
| writer.write("</ul>"); |
| } |
| writer.write("</body></html>"); |
| writer.flush(); |
| } |
| |
| private void getFolderDataDocContent(Writer writer, |
| SiteDataStub.FolderData f) throws IOException { |
| if (f.getFolders() != null) { |
| writer.write("<p>Folders</p><ul>"); |
| for (SiteDataStub.Folders folders : f.getFolders()) { |
| if (folders.getFolder() != null) { |
| for (SiteDataStub.Folder_type0 folder : folders.getFolder()) { |
| writer.write(liUrl(folder.getURL())); |
| } |
| } |
| } |
| writer.write("</ul>"); |
| } |
| if (f.getFiles() != null) { |
| writer.write("<p>Files</p><ul>"); |
| for (SiteDataStub.Files files : f.getFiles()) { |
| if (files.getFile() != null) { |
| for (SiteDataStub.File_type0 file : files.getFile()) { |
| writer.write(liUrl(file.getURL())); |
| } |
| } |
| } |
| writer.write("</ul>"); |
| } |
| } |
| |
| private void recurseFile(String id, String url, String prefix) |
| throws Exception { |
| System.out.println(prefix + "File: " + url); |
| prefix += " "; |
| System.out.println(prefix + "ID=" + id); |
| } |
| |
| private void getListItemDocContent(Request request, Response response, |
| String listId, String itemId) throws Exception { |
| //SiteDataStub.ItemData i = getContentItem(listId, itemId); |
| HttpClient client = new HttpClient(); |
| client.getParams().setAuthenticationPreemptive(true); |
| Credentials creds |
| = new UsernamePasswordCredentials(username, password); |
| client.getState().setCredentials(AuthScope.ANY, creds); |
| String url = request.getDocId().getUniqueId(); |
| String[] parts = url.split("/", 4); |
| url = parts[0] + "/" + parts[1] + "/" + parts[2] + "/" + |
| new URI(null, null, parts[3], null).toASCIIString(); |
| GetMethod method = new GetMethod(url); |
| int statusCode = client.executeMethod(method); |
| if (statusCode != HttpStatus.SC_OK) { |
| throw new RuntimeException("Got status code: " + statusCode); |
| } |
| InputStream is = method.getResponseBodyAsStream(); |
| IOHelper.copyStream(is, response.getOutputStream()); |
| } |
| |
| private SiteDataStub.VirtualServer getContentVirtualServer() |
| throws Exception { |
| SiteDataStub.GetContent request = new SiteDataStub.GetContent(); |
| request.setObjectType(SiteDataStub.ObjectType.VirtualServer); |
| request.setRetrieveChildItems(true); |
| request.setSecurityOnly(false); |
| SiteDataStub.GetContentResponse response = stub.getContent(request); |
| if (DEBUG) { |
| System.out.println(" VirtualServer"); |
| System.out.println(response.getLastItemIdOnPage()); |
| System.out.println(response.getGetContentResult()); |
| } |
| String xml = response.getGetContentResult(); |
| xml = xml.replace("<VirtualServer>", |
| "<VirtualServer xmlns='" + XMLNS + "'>"); |
| XMLStreamReader reader = xmlInputFactory.createXMLStreamReader( |
| new StringReader(xml)); |
| return SiteDataStub.VirtualServer.Factory.parse(reader); |
| } |
| |
| private SiteDataClient getClientForUrl(String url) throws Exception { |
| SiteDataStub.GetSiteUrl request = new SiteDataStub.GetSiteUrl(); |
| request.setUrl(url); |
| SiteDataStub.GetSiteUrlResponse response = stub.getSiteUrl(request); |
| return getSiteDataClient(response.getSiteUrl()); |
| } |
| |
| private SiteDataStub.ContentDatabase getContentContentDatabase(String id) |
| throws Exception { |
| SiteDataStub.GetContent request = new SiteDataStub.GetContent(); |
| request.setObjectType(SiteDataStub.ObjectType.ContentDatabase); |
| request.setRetrieveChildItems(true); |
| request.setSecurityOnly(false); |
| request.setObjectId(id); |
| SiteDataStub.GetContentResponse response = stub.getContent(request); |
| if (DEBUG) { |
| System.out.println(" ContentDatabase"); |
| System.out.println(response.getLastItemIdOnPage()); |
| System.out.println(response.getGetContentResult()); |
| } |
| String xml = response.getGetContentResult(); |
| xml = xml.replace("<ContentDatabase>", |
| "<ContentDatabase xmlns='" + XMLNS + "'>"); |
| XMLStreamReader reader = xmlInputFactory.createXMLStreamReader( |
| new StringReader(xml)); |
| return SiteDataStub.ContentDatabase.Factory.parse(reader); |
| } |
| |
| private SiteDataStub.Web getContentWeb(String id) throws Exception { |
| SiteDataStub.GetContent request = new SiteDataStub.GetContent(); |
| request.setObjectType(SiteDataStub.ObjectType.Site); |
| request.setRetrieveChildItems(true); |
| request.setSecurityOnly(false); |
| request.setObjectId(id); |
| SiteDataStub.GetContentResponse response = stub.getContent(request); |
| if (DEBUG) { |
| System.out.println(" Web"); |
| System.out.println(id); |
| System.out.println(response.getLastItemIdOnPage()); |
| System.out.println(response.getGetContentResult()); |
| } |
| stub.getContent(request); |
| String xml = response.getGetContentResult(); |
| xml = xml.replace("<Web>", "<Web xmlns='" + XMLNS + "'>"); |
| XMLStreamReader reader = xmlInputFactory.createXMLStreamReader( |
| new StringReader(xml)); |
| return SiteDataStub.Web.Factory.parse(reader); |
| } |
| |
| private SiteDataStub.List getContentList(String id) throws Exception { |
| SiteDataStub.GetContent request = new SiteDataStub.GetContent(); |
| request.setObjectType(SiteDataStub.ObjectType.List); |
| request.setRetrieveChildItems(true); |
| request.setSecurityOnly(false); |
| request.setObjectId(id); |
| SiteDataStub.GetContentResponse response = stub.getContent(request); |
| if (DEBUG) { |
| System.out.println(" List"); |
| System.out.println(response.getLastItemIdOnPage()); |
| System.out.println(response.getGetContentResult()); |
| } |
| String xml = response.getGetContentResult(); |
| xml = xml.replace("<List>", "<List xmlns='" + XMLNS + "'>"); |
| XMLStreamReader reader = xmlInputFactory.createXMLStreamReader( |
| new StringReader(xml)); |
| return SiteDataStub.List.Factory.parse(reader); |
| } |
| |
| private SiteDataStub.ItemData getContentItem(String listId, String itemId) |
| throws Exception { |
| SiteDataStub.GetContent request = new SiteDataStub.GetContent(); |
| request.setObjectType(SiteDataStub.ObjectType.ListItem); |
| request.setRetrieveChildItems(true); |
| request.setSecurityOnly(false); |
| request.setObjectId(listId); |
| request.setFolderUrl(""); |
| request.setItemId(itemId); |
| SiteDataStub.GetContentResponse response = stub.getContent(request); |
| if (DEBUG) { |
| System.out.println(" ListItem"); |
| System.out.println(response.getLastItemIdOnPage()); |
| System.out.println(response.getGetContentResult()); |
| } |
| String xml = response.getGetContentResult(); |
| xml = xml.replace("<Item>", "<ItemData xmlns='" + XMLNS + "'>"); |
| xml = xml.replace("</Item>", "</ItemData>"); |
| XMLStreamReader reader = xmlInputFactory.createXMLStreamReader( |
| new StringReader(xml)); |
| return SiteDataStub.ItemData.Factory.parse(reader); |
| } |
| |
| private SiteDataStub.FPFolder getContentFolder(String url) |
| throws Exception { |
| SiteDataStub.GetContent request = new SiteDataStub.GetContent(); |
| request.setObjectType(SiteDataStub.ObjectType.Folder); |
| request.setRetrieveChildItems(true); |
| request.setSecurityOnly(false); |
| request.setFolderUrl(url); |
| SiteDataStub.GetContentResponse response = stub.getContent(request); |
| if (DEBUG) { |
| System.out.println(" Folder (Specific)"); |
| System.out.println(response.getLastItemIdOnPage()); |
| System.out.println(response.getGetContentResult()); |
| } |
| String xml = response.getGetContentResult(); |
| xml = xml.replace("<FPFolder>", "<FPFolder xmlns='" + XMLNS + "'>"); |
| XMLStreamReader reader = xmlInputFactory.createXMLStreamReader( |
| new StringReader(xml)); |
| return SiteDataStub.FPFolder.Factory.parse(reader); |
| } |
| } |
| } |