/** * Copyright 2010 JBoss Inc * * 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 org.guvnor.tools.utils.webdav; import java.io.InputStream; import java.net.URL; import java.util.Iterator; import java.util.Map; import java.util.Properties; import java.util.StringTokenizer; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.webdav.IContext; import org.eclipse.webdav.ILocator; import org.eclipse.webdav.IResponse; import org.eclipse.webdav.client.RemoteDAVClient; import org.eclipse.webdav.client.WebDAVFactory; import org.eclipse.webdav.http.client.HttpClient; import org.eclipse.webdav.http.client.IAuthenticator; import org.guvnor.tools.Activator; /** * WebDav wrapper client. * @author jgraham * */ public class WebDavClient implements IWebDavClient { private RemoteDAVClient client; private WebDavAuthenticator platformAuthenticator; /** * Ctor for this wrapper WebDav client. * @param serverUrl The WebDav repository location (server) */ /** package */ WebDavClient(URL serverUrl) { HttpClient httpClient = null; if (Activator.getDefault().useDebugHttpClient()) { httpClient = new DebugHttpClient(); } else { httpClient = new HttpClient(); } platformAuthenticator = new WebDavAuthenticator(serverUrl); httpClient.setAuthenticator(platformAuthenticator); client = new RemoteDAVClient(new WebDAVFactory(), httpClient); } /* * (non-Javadoc) * @see org.guvnor.tools.utils.webdav.IWebDavClient#setSessionAuthenticator(org.eclipse.webdav.http.client.IAuthenticator) */ public void setSessionAuthenticator(IAuthenticator sessionAuthen) { if (sessionAuthen != null) { client.getHttpClient().setAuthenticator(sessionAuthen); } else { client.getHttpClient().setAuthenticator(platformAuthenticator); } } /* * (non-Javadoc) * @see org.guvnor.tools.utils.webdav.IWebDavClient#getClient() */ public RemoteDAVClient getClient() { return client; } /* * (non-Javadoc) * @see org.guvnor.tools.utils.webdav.IWebDavClient#createContext() */ public IContext createContext() { IContext context = WebDAVFactory.contextFactory.newContext(); // Need to make sure the USER-AGENT header is present for Guvnor context.put("USER-AGENT", "guvnor"); //$NON-NLS-1$ //$NON-NLS-2$ return context; } /* * (non-Javadoc) * @see org.guvnor.tools.utils.webdav.IWebDavClient#listDirectory(java.lang.String) */ public Map<String, ResourceProperties> listDirectory(String path) throws Exception { IResponse response = null; try { IContext context = createContext(); context.put("Depth", "1"); //$NON-NLS-1$ //$NON-NLS-2$ ILocator locator = WebDAVFactory.locatorFactory.newLocator(path); response = client.propfind(locator, context, null); if (response.getStatusCode() != IResponse.SC_MULTI_STATUS) { throw new WebDavException(response); } Map<String, ResourceProperties> res = StreamProcessingUtils.parseListing(path, response.getInputStream()); addGuvnorResourceProperties(res, path); return res; } finally { if (response != null) { response.close(); } } } private void addGuvnorResourceProperties(Map<String, ResourceProperties> props, String path) throws Exception { IResponse response = null; try { String apiVer = changeToAPICall(path); Properties guvProps = new Properties(); response = getResourceInputStream(apiVer); guvProps.load(response.getInputStream()); response.getInputStream(); for (Iterator<String> it = props.keySet().iterator(); it.hasNext();) { String oneKey = it.next(); String val = guvProps.getProperty(oneKey); if (val != null) { ResourceProperties resProps = props.get(oneKey); StringTokenizer tokens = new StringTokenizer(val, ","); //$NON-NLS-1$ // String dateStamp = tokens.nextToken(); // String revision = tokens.nextToken(); if(tokens.hasMoreElements()){ resProps.setLastModifiedDate(tokens.nextToken()); } if(tokens.hasMoreElements()){ resProps.setRevision(tokens.nextToken()); } } } } finally { if (response != null) { response.close(); } } } /* * (non-Javadoc) * @see org.guvnor.tools.utils.webdav.IWebDavClient#queryProperties(java.lang.String) */ public ResourceProperties queryProperties(String resource) throws Exception { IResponse response = null; try { IContext context = createContext(); context.put("Depth", "1"); //$NON-NLS-1$ //$NON-NLS-2$ ILocator locator = WebDAVFactory.locatorFactory.newLocator(resource); response = client.propfind(locator, context, null); if (response.getStatusCode() != IResponse.SC_MULTI_STATUS && response.getStatusCode() != IResponse.SC_OK) { throw new WebDavException(response); } Map<String, ResourceProperties> props = StreamProcessingUtils.parseListing("", response.getInputStream()); //$NON-NLS-1$ if (props.keySet().size() != 1) { throw new Exception(props.keySet().size() + " entries found for " + resource); //$NON-NLS-1$ } String fullpath = props.keySet().iterator().next(); ResourceProperties res = props.get(fullpath); String filename = new Path(fullpath).lastSegment(); addGuvnorResourceProperties(res, filename, resource); return res; } finally { if (response != null) { response.close(); } } } /** * Adds Guvnor-specific resource properties to the collection. * @param props The resource properties colleciton * @param filename The name of the resource * @param resource The full path to the resource in Guvnor * @throws Exception */ private void addGuvnorResourceProperties(ResourceProperties props, String filename, String resource) throws Exception { if (props == null) { return; } IResponse response = null; try { String path = resource.substring(0, resource.lastIndexOf('/')); String apiVer = changeToAPICall(path); Properties guvProps = new Properties(); response = getResourceInputStream(apiVer); guvProps.load(response.getInputStream()); String val = guvProps.getProperty(filename); if (val != null) { StringTokenizer tokens = new StringTokenizer(val, ","); //$NON-NLS-1$ // String dateStamp = tokens.nextToken(); // String revision = tokens.nextToken(); if(tokens.hasMoreElements()){ props.setLastModifiedDate(tokens.nextToken()); } if(tokens.hasMoreElements()){ props.setRevision(tokens.nextToken()); } } else { Exception nfe = new Exception("Failed to get Guvnor properties for " + filename); //$NON-NLS-1$ Activator.getDefault().writeLog(IStatus.WARNING, nfe.getMessage(), nfe); } } finally { if (response != null) { response.close(); } } } /* * (non-Javadoc) * @see org.guvnor.tools.utils.webdav.IWebDavClient#getResourceContents(java.lang.String) */ public String getResourceContents(String resource) throws Exception { IResponse response = null; try { response = getResourceInputStream(resource); return StreamProcessingUtils.getStreamContents(response.getInputStream()); } finally { if (response != null) { response.close(); } } } /* * (non-Javadoc) * @see org.guvnor.tools.utils.webdav.IWebDavClient#getResourceVersionContents(java.lang.String, java.lang.String) */ public String getResourceVersionContents(String resource, String version) throws Exception { String apiVer = changeToAPICall(resource) + "?version=" + version; //$NON-NLS-1$ return getResourceContents(apiVer); } /* * (non-Javadoc) * @see org.guvnor.tools.utils.webdav.IWebDavClient#getInputStream(java.lang.String) */ public IResponse getResourceInputStream(String resource) throws Exception { ILocator locator = WebDAVFactory.locatorFactory.newLocator(resource); IResponse response = client.get(locator, createContext()); if (response.getStatusCode() != IResponse.SC_OK) { throw new WebDavException(response); } return response; } /* * (non-Javadoc) * @see org.guvnor.tools.utils.webdav.IWebDavClient#getResourceVersionInputStream(java.lang.String, java.lang.String) */ public IResponse getResourceVersionInputStream(String resource, String version) throws Exception { String apiVer = changeToAPICall(resource) + "?version=" + version; //$NON-NLS-1$ return getResourceInputStream(apiVer); } /* * (non-Javadoc) * @see org.guvnor.tools.utils.webdav.IWebDavClient#createResource(java.lang.String, java.io.InputStream) */ public boolean createResource(String resource, InputStream is) throws Exception { return createResource(resource, is, true); } /* * (non-Javadoc) * @see org.guvnor.tools.utils.webdav.IWebDavClient#createResource(java.lang.String, java.io.InputStream, boolean) */ public boolean createResource(String resource, InputStream is, boolean overwrite) throws Exception { boolean res = true; if (!overwrite) { try { if (queryProperties(resource) != null) { res = false; } } catch (WebDavException e) { if (e.getErrorCode() != IResponse.SC_NOT_FOUND) { throw e; } } } IResponse response = null; try { if (res) { ILocator locator = WebDAVFactory.locatorFactory.newLocator(resource); response = client.put(locator, createContext(), is); if (response.getStatusCode() != IResponse.SC_OK && response.getStatusCode() != IResponse.SC_CREATED) { throw new WebDavException(response); } } } finally { if (response != null) { response.close(); } } return res; } /* * (non-Javadoc) * @see org.guvnor.tools.utils.webdav.IWebDavClient#putResource(java.lang.String, java.io.InputStream) */ public void putResource(String resource, InputStream is) throws Exception { IResponse response = null; try { ILocator locator = WebDAVFactory.locatorFactory.newLocator(resource); response = client.put(locator, createContext(), is); if (response.getStatusCode() != IResponse.SC_OK && response.getStatusCode() != IResponse.SC_NO_CONTENT && response.getStatusCode() != IResponse.SC_CREATED) { throw new WebDavException(response); } } finally { if (response != null) { response.close(); } } } /* * (non-Javadoc) * @see org.guvnor.tools.utils.webdav.IWebDavClient#getResourceVersions(java.lang.String) */ public IResponse getResourceVersions(String resource) throws Exception { String apiVer = changeToAPICall(resource) + "?version=all"; //$NON-NLS-1$ return getResourceInputStream(apiVer); } /* * (non-Javadoc) * @see org.guvnor.tools.utils.webdav.IWebDavClient#deleteResource(java.lang.String) */ public void deleteResource(String resource) throws Exception { IResponse response = null; try { ILocator locator = WebDAVFactory.locatorFactory.newLocator(resource); response = client.delete(locator, createContext()); if (response.getStatusCode() != IResponse.SC_NO_CONTENT && response.getStatusCode() != IResponse.SC_OK) { throw new WebDavException(response); } } finally { if (response != null) { response.close(); } } } /** * Converts the WedDav resource path to a Guvnor "API path." */ private String changeToAPICall(String path) { return path.replaceFirst("/webdav/", "/api/"); //$NON-NLS-1$ //$NON-NLS-2$ } }