manifoldcf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rh...@apache.org
Subject svn commit: r1695542 [2/3] - in /manifoldcf/branches/CONNECTORS-1161: connectors/ connectors/confluence/ connectors/confluence/connector/ connectors/confluence/connector/src/ connectors/confluence/connector/src/main/ connectors/confluence/connector/src...
Date Wed, 12 Aug 2015 14:45:45 GMT
Added: manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/client/ConfluenceClient.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/client/ConfluenceClient.java?rev=1695542&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/client/ConfluenceClient.java (added)
+++ manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/client/ConfluenceClient.java Wed Aug 12 14:45:43 2015
@@ -0,0 +1,727 @@
+package org.apache.manifoldcf.crawler.connectors.confluence.client;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.List;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.config.SocketConfig;
+import org.apache.http.conn.HttpClientConnectionManager;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.DefaultRedirectStrategy;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.http.protocol.HttpRequestExecutor;
+import org.apache.http.util.EntityUtils;
+import org.apache.manifoldcf.connectorcommon.common.InterruptibleSocketFactory;
+import org.apache.manifoldcf.connectorcommon.interfaces.KeystoreManagerFactory;
+import org.apache.manifoldcf.core.interfaces.ManifoldCFException;
+import org.apache.manifoldcf.crawler.connectors.confluence.exception.ConfluenceException;
+import org.apache.manifoldcf.crawler.connectors.confluence.model.Attachment;
+import org.apache.manifoldcf.crawler.connectors.confluence.model.ConfluenceResource;
+import org.apache.manifoldcf.crawler.connectors.confluence.model.ConfluenceResponse;
+import org.apache.manifoldcf.crawler.connectors.confluence.model.ConfluenceUser;
+import org.apache.manifoldcf.crawler.connectors.confluence.model.Label;
+import org.apache.manifoldcf.crawler.connectors.confluence.model.MutableAttachment;
+import org.apache.manifoldcf.crawler.connectors.confluence.model.MutablePage;
+import org.apache.manifoldcf.crawler.connectors.confluence.model.Page;
+import org.apache.manifoldcf.crawler.connectors.confluence.model.Space;
+import org.apache.manifoldcf.crawler.connectors.confluence.model.Spaces;
+import org.apache.manifoldcf.crawler.connectors.confluence.model.builder.ConfluenceResourceBuilder;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+
+/**
+ * <p>
+ * ConfluenceClient class
+ * </p>
+ * <p>
+ * This class is intended to be used to interact with Confluence REST API
+ * </p>
+ * <p>
+ * There are some methods that make use of the Confluence JSON-RPC 2.0 API, but
+ * until all the methods are ported to the new REST API, we will have to use
+ * them to leverage all the features provided by Confluence
+ * </p>
+ * 
+ * @author Antonio David Perez Morales <adperezmorales@gmail.com>
+ *
+ */
+public class ConfluenceClient {
+
+	private static final String VIEW_PERMISSION = "view";
+	
+	private static final String CONTENT_PATH = "/rest/api/content";
+	private static final String AUTHORITY_PATH = "/rpc/json-rpc/confluenceservice-v2/";
+	private static final String EXPANDABLE_PARAMETERS = "expand=body.view,metadata.labels,space,history,version";
+	private static final String CHILD_ATTACHMENTS_PATH = "/child/attachment/";
+	private static final String LABEL_PATH = "/label";
+
+	private Logger logger = LoggerFactory.getLogger(ConfluenceClient.class);
+
+	private String protocol;
+	private Integer port;
+	private String host;
+	private String path;
+	private String username;
+	private String password;
+
+	private CloseableHttpClient httpClient;
+	private HttpClientContext httpContext;
+
+	/**
+	 * <p>Creates a new client instance using the given parameters</p>
+	 * @param protocol the protocol
+	 * @param host the host
+	 * @param port the port
+	 * @param path the path to Confluence instance
+	 * @param username the username used to make the requests. Null or empty to use anonymous user
+	 * @param password the password
+	 * @throws ManifoldCFException 
+	 */
+	public ConfluenceClient(String protocol, String host, Integer port,
+			String path, String username, String password) throws ManifoldCFException {
+		this.protocol = protocol;
+		this.host = host;
+		this.port = port;
+		this.path = path;
+		this.username = username;
+		this.password = password;
+
+		connect();
+	}
+
+	/**
+	 * <p>Connect methods used to initialize the underlying client</p>
+	 * @throws ManifoldCFException 
+	 */
+	private void connect() throws ManifoldCFException {
+
+	    int socketTimeout = 900000;
+	    int connectionTimeout = 60000;
+
+	    javax.net.ssl.SSLSocketFactory httpsSocketFactory = KeystoreManagerFactory.getTrustingSecureSocketFactory();
+	    SSLConnectionSocketFactory myFactory = new SSLConnectionSocketFactory(new InterruptibleSocketFactory(httpsSocketFactory,connectionTimeout),
+	      SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+
+	    HttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
+
+	    // If authentication needed, set that
+	    // Preemptive authentication not working
+	    /*if (username != null)
+	    {
+	    	CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+	    	credentialsProvider.setCredentials(
+	    			AuthScope.ANY,
+	    			new UsernamePasswordCredentials(username,password));
+
+	    	AuthCache authCache = new BasicAuthCache();
+	    	authCache.put(new HttpHost(host, port), new BasicScheme());
+	    	httpContext = HttpClientContext.create();
+	    	httpContext.setCredentialsProvider(credentialsProvider);
+	    	httpContext.setAuthCache(authCache);
+	    }*/
+
+	    RequestConfig.Builder requestBuilder = RequestConfig.custom()
+	      .setCircularRedirectsAllowed(true)
+	      .setSocketTimeout(socketTimeout)
+	      .setStaleConnectionCheckEnabled(true)
+	      .setExpectContinueEnabled(true)
+	      .setConnectTimeout(connectionTimeout)
+	      .setConnectionRequestTimeout(socketTimeout);
+
+
+	    httpClient = HttpClients.custom()
+	      .setConnectionManager(connectionManager)
+	      .setMaxConnTotal(1)
+	      .disableAutomaticRetries()
+	      .setDefaultRequestConfig(requestBuilder.build())
+	      .setDefaultSocketConfig(SocketConfig.custom()
+	        .setTcpNoDelay(true)
+	        .setSoTimeout(socketTimeout)
+	        .build())
+	      .setSSLSocketFactory(myFactory)
+	      .setRequestExecutor(new HttpRequestExecutor(socketTimeout))
+	      .setRedirectStrategy(new DefaultRedirectStrategy())
+	      .build();
+	    
+	   }
+
+	/**
+	 * <p>Close the client. No further requests can be done</p>
+	 */
+	public void close() {
+		if (httpClient != null) {
+			try {
+				httpClient.close();
+			} catch (IOException e) {
+				logger.debug("Error closing http connection. Reason: {}",
+						e.getMessage());
+				e.printStackTrace();
+			}
+		}
+	}
+
+	/**
+	 * <p>Check method used to test if Confluence instance is up and running</p>
+	 * 
+	 * @return a {@code Boolean} indicating whether the Confluence instance is alive or not
+	 * 
+	 * @throws Exception
+	 */
+	public boolean check() throws Exception {
+		HttpResponse response;
+		try {
+			if (httpClient == null) {
+				connect();
+			}
+
+			String url = String.format("%s://%s:%s/%s/%s?limit=1", protocol, host,
+					port, path, CONTENT_PATH);
+			logger.debug(
+					"[Processing] Hitting url: {} for confluence status check fetching : ",
+					"Confluence URL", sanitizeUrl(url));
+			HttpGet httpGet = createGetRequest(url);
+			response = httpClient.execute(httpGet);
+			int statusCode = response.getStatusLine().getStatusCode();
+			if (statusCode != 200)
+				throw new Exception(
+						"[Checking connection] Confluence server appears to be down");
+			else
+				return true;
+		} catch (IOException e) {
+			logger.warn(
+					"[Checking connection] Confluence server appears to be down",
+					e);
+			throw new Exception("Confluence appears to be down", e);
+		}
+	}
+
+	/**
+	 * <p>Check method used to test if Confluence instance is up and running when using Authority connector (JSON-RPC API)</p>
+	 * <p>This method will be deleted when all JSON-RPC methods are available through the REST API
+	 * 
+	 * @return a {@code Boolean} indicating whether the Confluence instance is alive or not
+	 * 
+	 * @throws Exception
+	 */
+	public boolean checkAuth() throws Exception {
+		try {
+			if (httpClient == null) {
+				connect();
+			}
+			getSpaces();
+			return true;
+		} catch (Exception e) {
+			logger.warn(
+					"[Checking connection] Confluence server appears to be down",
+					e);
+			throw e;
+		}
+	}
+	/**
+	 * <p>
+	 * Create a get request for the given url
+	 * </p>
+	 * 
+	 * @param url
+	 *            the url
+	 * @return the created {@code HttpGet} instance
+	 */
+	private HttpGet createGetRequest(String url) {
+		String finalUrl = useBasicAuthentication() ? url + "&os_authType=basic": url;
+		String sanitizedUrl = sanitizeUrl(finalUrl);
+		HttpGet httpGet = new HttpGet(sanitizedUrl);
+		httpGet.addHeader("Accept", "application/json");
+		if (useBasicAuthentication()) {
+			httpGet.addHeader(
+					"Authorization",
+					"Basic "
+							+ Base64.encodeBase64String(String.format("%s:%s",
+									this.username, this.password).getBytes(
+									Charset.forName("UTF-8"))));
+		}
+		return httpGet;
+	}
+
+	/**
+	 * <p>
+	 * Get a list of Confluence pages
+	 * </p>
+	 * 
+	 * @return a {@code ConfluenceResponse} containing the result pages and
+	 *         some pagination values
+	 * @throws Exception
+	 */
+	public ConfluenceResponse<Page> getPages() throws Exception {
+		return getPages(0, 50, Optional.<String> absent());
+	}
+
+	/**
+	 * <p>
+	 * Get a list of Confluence pages using pagination
+	 * </p>
+	 * 
+	 * @param start The start value to get pages from
+	 * @param limit The number of pages to get from start
+	 * @return a {@code ConfluenceResponse} containing the result pages and
+	 *         some pagination values
+	 * @throws Exception
+	 */
+	@SuppressWarnings("unchecked")
+	public ConfluenceResponse<Page> getPages(int start, int limit,
+			Optional<String> space) throws Exception {
+		String url = String.format("%s://%s:%s/%s/%s?limit=%s&start=%s", protocol,
+				host, port, path, CONTENT_PATH, limit, start);
+		if (space.isPresent()) {
+			url = String.format("%s&spaceKey=%s", url, space.get());
+		}
+		return (ConfluenceResponse<Page>) getConfluenceResources(url, Page.builder());
+	}
+
+	/**
+	 * <p>Get the {@code ConfluenceResources} from the given url</p>
+	 * @param url The url identifying the REST resource to get the documents
+	 * @param builder The builder used to build the resources contained in the response
+	 * @return a {@code ConfluenceResponse} containing the page results
+	 * @throws Exception
+	 */
+	private ConfluenceResponse<? extends ConfluenceResource> getConfluenceResources(String url, ConfluenceResourceBuilder<? extends ConfluenceResource> builder) throws Exception {
+		logger.debug("[Processing] Hitting url for get confluence resources: {}", sanitizeUrl(url));
+
+		try {
+			HttpGet httpGet = createGetRequest(url);
+			HttpResponse response = executeRequest(httpGet);
+			ConfluenceResponse<? extends ConfluenceResource> confluenceResponse = responseFromHttpEntity(response
+					.getEntity(), builder);
+			EntityUtils.consume(response.getEntity());
+			return confluenceResponse;
+		} catch (IOException e) {
+			logger.error("[Processing] Failed to get page(s)", e);
+			throw new Exception("Confluence appears to be down", e);
+		}
+	}
+
+	/**
+	 * <p>Creates a ConfluenceResponse from the entity returned in the HttpResponse</p>
+	 * @param entity the {@code HttpEntity} to extract the response from
+	 * @return a {@code ConfluenceResponse} with the requested information
+	 * @throws Exception
+	 */
+	private <T extends ConfluenceResource> ConfluenceResponse<T> responseFromHttpEntity(HttpEntity entity, ConfluenceResourceBuilder<T> builder)
+			throws Exception {
+		String stringEntity = EntityUtils.toString(entity);
+
+		JSONObject responseObject;
+		try {
+			responseObject = new JSONObject(stringEntity);
+			ConfluenceResponse<T> response = ConfluenceResponse
+					.fromJson(responseObject, builder);
+			if (response.getResults().size() == 0) {
+				logger.debug("[Processing] No {} found in the Confluence response", builder.getType().getSimpleName());
+			}
+
+			return response;
+		} catch (JSONException e) {
+			logger.debug("Error parsing JSON response");
+			throw new Exception();
+		}
+
+	}
+	
+	/**
+	 * <p>Get the attachments of the given page</p>
+	 * @param pageId the page id
+	 * @return a {@code ConfluenceResponse} instance containing the attachment results and some pagination values</p>
+	 * @throws Exception
+	 */
+	public ConfluenceResponse<Attachment> getPageAttachments(String pageId)
+			throws Exception {
+		return getPageAttachments(pageId, 0, 50);
+	}
+
+	/**
+	 * <p>Get the attachments of the given page using pagination</p>
+	 * @param pageId the page id
+	 * @param start The start value to get attachments from
+	 * @param limit The number of attachments to get from start
+	 * @return a {@code ConfluenceResponse} instance containing the attachment results and some pagination values</p>
+	 * @throws Exception
+	 */
+	public ConfluenceResponse<Attachment> getPageAttachments(String pageId, int start,
+			int limit) throws Exception {
+		String url = String.format("%s://%s:%s/%s/%s/%s%s?limit=%s&start=%s",
+				protocol, host, port, path, CONTENT_PATH, pageId, CHILD_ATTACHMENTS_PATH,
+				limit, start);
+		@SuppressWarnings("unchecked")
+		ConfluenceResponse<Attachment> confluenceResources = (ConfluenceResponse<Attachment>) getConfluenceResources(url, Attachment.builder());
+		return confluenceResources;
+	}
+	
+	/**
+	 * <p>
+	 * Gets a specific attachment contained in the specific page
+	 * </p>
+	 * 
+	 * @param attachmentId
+	 * @param pageId
+	 * @return the {@code Attachment} instance
+	 */
+	public Attachment getAttachment(String attachmentId) {
+		String url = String
+				.format("%s://%s:%s/%s/%s/%s?%s",
+						protocol, host, port, path, CONTENT_PATH, attachmentId, EXPANDABLE_PARAMETERS);
+		logger.debug(
+				"[Processing] Hitting url for getting document content : {}",
+				sanitizeUrl(url));
+		try {
+			HttpGet httpGet = createGetRequest(url);
+			HttpResponse response = executeRequest(httpGet);
+			HttpEntity entity = response.getEntity();
+			MutableAttachment attachment = attachmentFromHttpEntity(entity);
+			EntityUtils.consume(entity);
+			retrieveAndSetAttachmentContent(attachment);
+			return attachment;
+		} catch (Exception e) {
+			logger.error("[Processing] Failed to get attachment {}. Error: {}",
+					url, e.getMessage());
+		}
+
+		return new Attachment();
+	}
+
+	/**
+	 * <p>
+	 * Downloads and retrieves the attachment content, setting it in the given
+	 * {@code Attachment} instance
+	 * </p>
+	 * 
+	 * @param attachment
+	 *            the {@code Attachment} instance to download and set the
+	 *            content
+	 * @throws Exception
+	 */
+	private void retrieveAndSetAttachmentContent(MutableAttachment attachment)
+			throws Exception {
+		StringBuilder sb = new StringBuilder();
+		sb.append(attachment.getBaseUrl()).append(attachment.getUrlContext())
+				.append(attachment.getDownloadUrl());
+		String url = sanitizeUrl(sb.toString());
+		logger.debug(
+				"[Processing] Hitting url for getting attachment content : {}",
+				url);
+		try {
+			HttpGet httpGet = createGetRequest(url);
+			HttpResponse response = executeRequest(httpGet);
+			attachment.setLength(response.getEntity().getContentLength());
+			byte[] byteContent = IOUtils.toByteArray(response.getEntity()
+					.getContent());
+			EntityUtils.consumeQuietly(response.getEntity());
+			attachment.setContentStream(new ByteArrayInputStream(byteContent));
+		} catch (Exception e) {
+
+			logger.error(
+					"[Processing] Failed to get attachment content from {}. Error: {}",
+					url, e.getMessage());
+			throw e;
+		}
+
+	}
+
+
+	/**
+	 * <p>Get a Confluence page identified by its id</p>
+	 * @param pageId the page id
+	 * @return the Confluence page
+	 */
+	public Page getPage(String pageId) {
+		String url = String
+				.format("%s://%s:%s/%s/%s/%s?%s",
+						protocol, host, port, path, CONTENT_PATH, pageId, EXPANDABLE_PARAMETERS);
+		url = sanitizeUrl(url);
+		logger.debug(
+				"[Processing] Hitting url for getting document content : {}",
+				url);
+		try {
+			HttpGet httpGet = createGetRequest(url);
+			HttpResponse response = executeRequest(httpGet);
+			HttpEntity entity = response.getEntity();
+			MutablePage page = pageFromHttpEntity(entity);
+			EntityUtils.consume(entity);
+			List<Label> labels = getLabels(pageId);
+			page.setLabels(labels);
+			return page;
+		} catch (Exception e) {
+			logger.error("[Processing] Failed to get page {0}. Error: {1}",
+					url, e.getMessage());
+		}
+
+		return new Page();
+	}
+
+	/**
+	 * <p>Get the labels of a specific page</p> 
+	 * @param pageId The pageId to get the labels
+	 * @return a {@code List<Label>} of labels
+	 */
+	public List<Label> getLabels(String pageId) {
+				
+		List<Label> labels = Lists.newArrayList();
+		int lastStart = 0;
+		int limit = 50;
+		boolean isLast = false;
+		do {
+			String url = String
+					.format("%s://%s:%s/%s/%s/%s/%s?start=%s&limit=%s",
+							protocol, host, port, path, CONTENT_PATH, pageId, LABEL_PATH, lastStart, limit);
+			url = sanitizeUrl(url);
+			logger.debug(
+					"[Processing] Hitting url for getting page labels : {}",
+					url);
+			try {
+				@SuppressWarnings("unchecked")
+				ConfluenceResponse<Label> response = (ConfluenceResponse<Label>) getConfluenceResources(url, Label.builder());
+				labels.addAll(response.getResults());
+				lastStart += response.getResults().size();
+				isLast = response.isLast();
+			} catch (Exception e) {
+				logger.debug("Error getting labels for page {}. Reason: {}", pageId, e.getMessage());
+			}
+		}
+		while(!isLast);
+		
+		return labels;
+	}
+	
+	/**
+	 * 
+	 * @param username
+	 * @return
+	 * @throws Exception
+	 */
+	public ConfluenceUser getUserAuthorities(String username) throws Exception {
+		List<String> authorities = Lists.<String>newArrayList();
+		Spaces spaces = getSpaces();
+		for(Space space: spaces) {
+			List<String> permissions = getSpacePermissionsForUser(space, username);
+			if(permissions.contains(VIEW_PERMISSION)) {
+				authorities.add(space.getKey());
+			}
+		}
+		
+		return new ConfluenceUser(username, authorities);
+	
+	}
+	
+	private HttpPost createPostRequest(String url) {
+		HttpPost httpPost = new HttpPost(url);
+		httpPost.addHeader("Accept", "application/json");
+		httpPost.addHeader("Content-Type", "application/json");
+		if (useBasicAuthentication()) {
+			httpPost.addHeader(
+					"Authorization",
+					"Basic "
+							+ Base64.encodeBase64String(String.format("%s:%s",
+									this.username, this.password).getBytes(
+									Charset.forName("UTF-8"))));
+		}
+		return httpPost;
+	}
+	
+	/**
+	 * <p>Execute the given {@code HttpUriRequest} using the configured client</p> 
+	 * @param request the {@code HttpUriRequest} to be executed
+	 * @return the {@code HttpResponse} object returned from the server
+	 * @throws Exception
+	 */
+	private HttpResponse executeRequest(HttpUriRequest request)
+			throws Exception {
+		String url = request.getURI().toString();
+		logger.debug(
+				"[Processing] Hitting url for getting document content : {}",
+				url);
+
+		try {
+			HttpResponse response = httpClient.execute(request, httpContext);
+			if (response.getStatusLine().getStatusCode() != 200) {
+				throw new Exception("Confluence error. "
+						+ response.getStatusLine().getStatusCode() + " "
+						+ response.getStatusLine().getReasonPhrase());
+			}
+			return response;
+		} catch (Exception e) {
+			logger.error("[Processing] Failed to get page {}. Error: {}",
+					url, e.getMessage());
+			throw e;
+		}
+	}
+
+	/**
+	 * <p>Creates a Confluence page object from the given entity returned by the server</p>
+	 * @param entity the {@code HttpEntity} to create the {@code MutablePage} from
+	 * @return the Confluence page instance
+	 * @throws Exception
+	 */
+	private MutablePage pageFromHttpEntity(HttpEntity entity) throws Exception {
+		String stringEntity = EntityUtils.toString(entity);
+
+		JSONObject responseObject;
+		try {
+			responseObject = new JSONObject(stringEntity);
+			@SuppressWarnings("unchecked")
+			MutablePage response = ((ConfluenceResourceBuilder<MutablePage>)MutablePage.builder()).fromJson(responseObject, new MutablePage());
+			return response;
+		} catch (JSONException e) {
+			logger.debug("Error parsing JSON page response data");
+			throw new Exception("Error parsing JSON page response data");
+		}
+	}
+
+	/**
+	 * <p>Creates a {@code MutableAttachment} object from the given entity returned by the server</p>
+	 * @param entity the {@code HttpEntity} to create the {@code MutableAttachment} from
+	 * @return the Confluence MutableAttachment instance
+	 * @throws Exception
+	 */
+	private MutableAttachment attachmentFromHttpEntity(HttpEntity entity)
+			throws Exception {
+		String stringEntity = EntityUtils.toString(entity);
+		JSONObject responseObject;
+		try {
+			responseObject = new JSONObject(stringEntity);
+			MutableAttachment response = (MutableAttachment) Attachment
+					.builder()
+					.fromJson(responseObject, new MutableAttachment());
+			return response;
+		} catch (JSONException e) {
+			logger.debug("Error parsing JSON page response data");
+			throw new Exception("Error parsing JSON page response data");
+		}
+	}
+
+	/**
+	 * <p>Method to check if basic authentication must be used</p>
+	 * @return {@code Boolean} indicating whether basic authentication must be used or not
+	 */
+	private boolean useBasicAuthentication() {
+		return this.username != null && !"".equals(username)
+				&& this.password != null;
+	}
+
+	/**
+	 * <p>
+	 * Sanitize the given url replacing the appearance of more than one slash by
+	 * only one slash
+	 * </p>
+	 * 
+	 * @param url
+	 *            The url to sanitize
+	 * @return the sanitized url
+	 */
+	private String sanitizeUrl(String url) {
+		int colonIndex = url.indexOf(":");
+		String urlWithoutProtocol = url.startsWith("http") ? url.substring(colonIndex+3) : url;
+		String sanitizedUrl = urlWithoutProtocol.replaceAll("\\/+", "/");
+		return url.substring(0,colonIndex) + "://" + sanitizedUrl;
+	}
+	
+	private Spaces getSpaces() throws Exception {
+		String url = String.format("%s://%s:%s%s%sgetSpaces", protocol, host,
+				port, path, AUTHORITY_PATH);
+
+		logger.debug(
+				"[Processing] Hitting url for getting Confluence spaces : {}",
+				url);
+
+		HttpPost httpPost = createPostRequest(url);
+		httpPost.setEntity(new StringEntity("[]"));
+		HttpResponse response = httpClient.execute(httpPost);
+		if (response.getStatusLine().getStatusCode() != 200) {
+			throw new ConfluenceException("Confluence error. "
+					+ response.getStatusLine().getStatusCode() + " "
+					+ response.getStatusLine().getReasonPhrase());
+		}
+		HttpEntity entity = response.getEntity();
+		Spaces spaces = spacesFromHttpEntity(entity);
+		EntityUtils.consume(entity);
+		return spaces;
+	}
+	
+	private List<String> getSpacePermissionsForUser(Space space, String username) throws Exception {
+		String url = String.format("%s://%s:%s%s%sgetPermissionsForUser", protocol, host,
+				port, path, AUTHORITY_PATH);
+
+		logger.debug(
+				"[Processing] Hitting url {} for getting Confluence permissions for user {} in space {}",
+				url, username, space.getKey());
+
+		HttpPost httpPost = createPostRequest(url);
+		JSONArray jsonArray = new JSONArray();
+		jsonArray.put(space.getKey());
+		jsonArray.put(username);
+		StringEntity stringEntity = new StringEntity(jsonArray.toString());
+		httpPost.setEntity(stringEntity);
+		HttpResponse response = httpClient.execute(httpPost);
+		if (response.getStatusLine().getStatusCode() != 200) {
+			throw new ConfluenceException("Confluence error. "
+					+ response.getStatusLine().getStatusCode() + " "
+					+ response.getStatusLine().getReasonPhrase());
+		}
+		HttpEntity entity = response.getEntity();
+		List<String> permissions = permissionsFromHttpEntity(entity);
+		EntityUtils.consume(entity);
+		return permissions;
+	}
+
+	private Spaces spacesFromHttpEntity(HttpEntity entity) throws Exception {
+		String stringEntity = EntityUtils.toString(entity);
+
+		JSONArray responseObject;
+		try {
+			responseObject = new JSONArray(stringEntity);
+			Spaces response = Spaces.fromJson(responseObject);
+
+			return response;
+		} catch (JSONException e) {
+			logger.debug("Error parsing JSON spaces response data");
+			throw new Exception("Error parsing JSON spaces response data");
+		}
+
+	}
+	
+	private List<String> permissionsFromHttpEntity(HttpEntity entity) throws Exception {
+		String stringEntity = EntityUtils.toString(entity);
+
+		JSONArray responseObject;
+		List<String> permissions = Lists.newArrayList();
+		try {
+			responseObject = new JSONArray(stringEntity);
+			for(int i=0,len=responseObject.length();i<len;i++) {
+				permissions.add(responseObject.getString(i));
+			}
+
+			return permissions;
+		} catch (JSONException e) {
+			logger.debug("Error parsing JSON space permissions response data");
+			throw new Exception("Error parsing JSON space permissions respnse data");
+		}
+
+	}
+}

Added: manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/exception/ConfluenceException.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/exception/ConfluenceException.java?rev=1695542&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/exception/ConfluenceException.java (added)
+++ manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/exception/ConfluenceException.java Wed Aug 12 14:45:43 2015
@@ -0,0 +1,17 @@
+package org.apache.manifoldcf.crawler.connectors.confluence.exception;
+
+public class ConfluenceException extends Exception {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 5903550079897330304L;
+
+	public ConfluenceException(String message) {
+		super(message);
+	}
+	
+	public ConfluenceException(String message, Throwable cause) {
+		super(message, cause);
+	}
+}

Added: manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/exception/PageNotFoundException.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/exception/PageNotFoundException.java?rev=1695542&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/exception/PageNotFoundException.java (added)
+++ manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/exception/PageNotFoundException.java Wed Aug 12 14:45:43 2015
@@ -0,0 +1,14 @@
+package org.apache.manifoldcf.crawler.connectors.confluence.exception;
+
+/**
+ * 
+ * @author Antonio David Perez Morales <adperezmorales@gmail.com>
+ *
+ */
+public class PageNotFoundException extends Exception {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+}
\ No newline at end of file

Added: manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/Attachment.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/Attachment.java?rev=1695542&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/Attachment.java (added)
+++ manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/Attachment.java Wed Aug 12 14:45:43 2015
@@ -0,0 +1,113 @@
+package org.apache.manifoldcf.crawler.connectors.confluence.model;
+
+import java.io.InputStream;
+import java.util.Map;
+
+import org.apache.manifoldcf.crawler.connectors.confluence.model.builder.ConfluenceResourceBuilder;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * <p>
+ * Attachment class
+ * </p>
+ * <p>
+ * Represents a Confluence Attachment
+ * </p>
+ * 
+ * @author Antonio David Perez Morales <adperezmorales@gmail.com>
+ */
+public class Attachment extends Page {
+
+	protected static final String KEY_DOWNLOAD = "download";
+	protected static final String KEY_EXTENSIONS = "extensions";
+	protected String downloadUrl;
+	protected InputStream contentStream;
+
+	public static ConfluenceResourceBuilder<Attachment> builder() {
+		return new AttachmentBuilder();
+	}
+
+	public String getDownloadUrl() {
+		return this.downloadUrl;
+	}
+
+	@Override
+	public boolean hasContent() {
+		return (this.length > 0 && this.hasContentStream()) || (this.downloadUrl != null && !this.downloadUrl.isEmpty());
+	}
+
+	public Boolean hasContentStream() {
+		return this.contentStream != null;
+	}
+
+	@Override
+	public InputStream getContentStream() {
+		if(hasContentStream()) {
+			return this.contentStream;
+		}
+		return super.getContentStream();
+	}
+
+	@Override
+	protected void refineMetadata(Map<String, Object> metadata) {
+		super.refineMetadata(metadata);
+		metadata.put("downloadUrl", this.getBaseUrl() + this.getUrlContext()
+				+ downloadUrl);
+	}
+
+	/**
+	 * <p>
+	 * AttachmentBuilder internal class
+	 * </p>
+	 * <p>
+	 * Used to build Attachments
+	 * </p>
+	 * 
+	 * @author Antonio David Perez Morales <adperezmorales@gmail.com>
+	 *
+	 */
+	public static class AttachmentBuilder implements ConfluenceResourceBuilder<Attachment>{
+		
+		@Override
+		public Attachment fromJson(JSONObject jsonPage) {
+			return fromJson(jsonPage, new Attachment());
+		}
+
+		@SuppressWarnings("unchecked")
+		public Attachment fromJson(JSONObject jsonPage, Attachment attachment) {
+			((ConfluenceResourceBuilder<Page>) Page.builder()).fromJson(jsonPage, attachment);
+
+			try {
+				/*
+				 * Download URL
+				 */
+
+				JSONObject links = (JSONObject) jsonPage.get(Page.KEY_LINKS);
+				if (links != null) {
+					attachment.downloadUrl = links.optString(KEY_DOWNLOAD, "");
+				}
+
+				/*
+				 * Extensions
+				 */
+				JSONObject extensions = (JSONObject) jsonPage
+						.get(KEY_EXTENSIONS);
+				if (extensions != null) {
+					attachment.mediaType = extensions.optString(
+							Page.KEY_MEDIATYPE, "");
+				}
+			} catch (JSONException e) {
+				e.printStackTrace();
+			}
+
+			return attachment;
+		}
+
+		@Override
+		public Class<Attachment> getType() {
+			return Attachment.class;
+		}
+
+	}
+}

Added: manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/ConfluenceResource.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/ConfluenceResource.java?rev=1695542&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/ConfluenceResource.java (added)
+++ manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/ConfluenceResource.java Wed Aug 12 14:45:43 2015
@@ -0,0 +1,12 @@
+package org.apache.manifoldcf.crawler.connectors.confluence.model;
+
+/**
+ * <p>ConfluenceResource class</p>
+ * <p>Used as base class for other classes like Page and Attachments</p>
+ * 
+ * @author Antonio David Perez Morales <adperezmorales@gmail.com> 
+ *
+ */
+public class ConfluenceResource {
+
+}

Added: manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/ConfluenceResponse.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/ConfluenceResponse.java?rev=1695542&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/ConfluenceResponse.java (added)
+++ manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/ConfluenceResponse.java Wed Aug 12 14:45:43 2015
@@ -0,0 +1,68 @@
+package org.apache.manifoldcf.crawler.connectors.confluence.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.manifoldcf.crawler.connectors.confluence.model.builder.ConfluenceResourceBuilder;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public class ConfluenceResponse<T extends ConfluenceResource> {
+
+	private List<T> results;
+	private int start;
+	private int limit;
+	private Boolean isLast;
+	
+	public ConfluenceResponse(List<T> results, int start, int limit, Boolean isLast) {
+		this.results = results;
+		this.start = start;
+		this.limit = limit;
+		this.isLast = isLast;
+	}
+	
+	public List<T> getResults() {
+		return this.results;
+	}
+	
+	public int getStart() {
+		return this.start;
+	}
+	
+	public int getLimit() {
+		return this.limit;
+	}
+	
+	public Boolean isLast() {
+		return isLast;
+	}
+	
+	public static <T extends ConfluenceResource> ConfluenceResponse<T> fromJson(JSONObject response, ConfluenceResourceBuilder<T> builder) {
+		List<T> resources = new ArrayList<T>();
+		try {
+			JSONArray jsonArray = response.getJSONArray("results");
+			for(int i=0,size=jsonArray.length(); i<size;i++) {
+				JSONObject jsonPage = jsonArray.getJSONObject(i);
+				T resource = (T) builder.fromJson(jsonPage);
+				resources.add(resource);
+			}
+			
+			int limit = response.getInt("limit");
+			int start = response.getInt("start");
+			Boolean isLast = false;
+			JSONObject links = response.getJSONObject("_links");
+			if(links != null) {
+				isLast = links.optString("next", "undefined").equalsIgnoreCase("undefined");
+			}
+			
+			return new ConfluenceResponse<T>(resources, start, limit, isLast);
+			
+		} catch (JSONException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		
+		return new ConfluenceResponse<T>(new ArrayList<T>(), 0,0,false);
+	}
+}

Added: manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/ConfluenceUser.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/ConfluenceUser.java?rev=1695542&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/ConfluenceUser.java (added)
+++ manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/ConfluenceUser.java Wed Aug 12 14:45:43 2015
@@ -0,0 +1,28 @@
+package org.apache.manifoldcf.crawler.connectors.confluence.model;
+
+import java.util.List;
+
+/**
+ * <p>ConfluenceUser class</p>
+ * <p>Represents a Confluence user</p>
+ * 
+ * @author Antonio David Perez Morales <adperezmorales@gmail.com>
+ *
+ */
+public class ConfluenceUser {
+	  private final String username;
+	  private final List<String> authorities;
+
+	  public ConfluenceUser(String username, List<String> authorities) {
+	    this.username = username;
+	    this.authorities = authorities;
+	  }
+
+	  public String getUsername() {
+	    return username;
+	  }
+
+	  public List<String> getAuthorities() {
+	    return authorities;
+	  }
+	}

Added: manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/Label.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/Label.java?rev=1695542&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/Label.java (added)
+++ manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/Label.java Wed Aug 12 14:45:43 2015
@@ -0,0 +1,86 @@
+package org.apache.manifoldcf.crawler.connectors.confluence.model;
+
+import org.apache.manifoldcf.crawler.connectors.confluence.model.builder.ConfluenceResourceBuilder;
+import org.json.JSONObject;
+
+/**
+ * <p>
+ * Label class
+ * </p>
+ * <p>
+ * Represents a Confluence Label
+ * </p>
+ * 
+ * @author Antonio David Perez Morales <adperezmorales@gmail.com>
+ */
+public class Label extends ConfluenceResource{
+
+	protected static final String KEY_LINKS = "_links";
+	protected static final String KEY_ID = "id";
+	protected static final String KEY_SELF = "self";
+	protected static final String KEY_PREFIX = "prefix";
+	protected static final String KEY_NAME = "name";
+
+	protected String id;
+	protected String prefix;
+	protected String name;
+
+	@SuppressWarnings("unused")
+	private JSONObject delegated;
+
+	public Label() {
+
+	}
+
+	public String getId() {
+		return this.id;
+	}
+
+	public String getPrefix() {
+		return this.prefix;
+	}
+
+	public String getName() {
+		return this.name;
+	}
+
+	public static LabelBuilder builder() {
+		return new LabelBuilder();
+	}
+
+	/**
+	 * <p>
+	 * LabelBuilder internal class
+	 * </p>
+	 * <p>
+	 * Used to build Labels
+	 * </p>
+	 * 
+	 * @author Antonio David Perez Morales <adperezmorales@gmail.com>
+	 *
+	 */
+	public static class LabelBuilder implements ConfluenceResourceBuilder<Label>{
+
+		public Label fromJson(JSONObject jsonLabel) {
+			return fromJson(jsonLabel, new Label());
+		}
+
+		public Label fromJson(JSONObject jsonPage, Label label) {
+
+			label.id = jsonPage.optString(KEY_ID, "");
+			label.prefix = jsonPage.optString(KEY_PREFIX, "");
+			label.name = jsonPage.optString(KEY_NAME, "");
+
+			label.delegated = jsonPage;
+
+			return label;
+
+		}
+
+		@Override
+		public Class<Label> getType() {
+			return Label.class;
+		}
+
+	}
+}

Added: manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/MutableAttachment.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/MutableAttachment.java?rev=1695542&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/MutableAttachment.java (added)
+++ manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/MutableAttachment.java Wed Aug 12 14:45:43 2015
@@ -0,0 +1,94 @@
+package org.apache.manifoldcf.crawler.connectors.confluence.model;
+
+import java.io.InputStream;
+import java.util.Date;
+
+/**
+ * <p>
+ * Mutable Attachment class
+ * </p>
+ * <p>
+ * Represents a Confluence Attachment which can be mutated
+ * </p>
+ * 
+ * @author Antonio David Perez Morales <adperezmorales@gmail.com>
+ */
+public class MutableAttachment extends Attachment {
+
+	public void setId(String id) {
+		this.id = id;
+	}
+	
+	public void setSpace(String space) {
+		this.space = space;
+	}
+
+	public void setBaseUrl(String baseUrl) {
+		this.baseUrl = baseUrl;
+	}
+
+	public void setUrlContext(String urlContext) {
+		this.urlContext = urlContext;
+	}
+	
+	public void setUrl(String url) {
+		this.url = url;
+	}
+	
+	public void setWebUrl(String webUrl) {
+		this.webUrl = webUrl;
+	}
+	
+	public void setCreatedDate(Date createdDate) {
+		this.createdDate = createdDate;
+	}
+	
+	public void setLastModified(Date lastModified) {
+		this.lastModified = lastModified;
+	}
+	
+	public void setType(PageType type) {
+		this.type = type;
+	}
+	
+	public void setTitle(String title) {
+		this.title = title;
+	}
+	
+	public void setVersion(int version) {
+		this.version = version;
+	}
+	
+	public void setCreator(String creator) {
+		this.creator = creator;
+	}
+	
+	public void setCreatorUsername(String creatorUsername) {
+		this.creatorUsername = creatorUsername;
+	}
+	
+	public void setLastModifier(String lastModifier) {
+		this.lastModifier = lastModifier;
+	}
+	
+	public void setLastModifierUsername(String lastModifierUsername) {
+		this.lastModifierUsername = lastModifierUsername;
+	}
+	
+	public void setMediaType(String mediaType) {
+		this.mediaType = mediaType;
+	}
+	
+	public void setLength(long length) {
+		this.length = length;
+	}
+	
+	public void setDownloadUrl(String downloadUrl) {
+		this.downloadUrl = downloadUrl;
+	}
+	
+	public void setContentStream(InputStream contentStream) {
+		this.contentStream = contentStream;
+	}	
+
+}

Added: manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/MutablePage.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/MutablePage.java?rev=1695542&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/MutablePage.java (added)
+++ manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/MutablePage.java Wed Aug 12 14:45:43 2015
@@ -0,0 +1,99 @@
+package org.apache.manifoldcf.crawler.connectors.confluence.model;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * <p>
+ * MutablePage class
+ * </p>
+ * <p>
+ * Represents a Confluence Page which is mutable unlike {@code Page} class which can be also initialized using the PageBuilder obtained from
+ * <code>Page.builder()</code> method
+ * </p>
+ * 
+ * @author Antonio David Perez Morales <adperezmorales@gmail.com>
+ */
+public class MutablePage extends Page {
+
+	public MutablePage() {
+
+	}
+	
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public void setSpace(String space) {
+		this.space = space;
+	}
+
+	public void setBaseUrl(String baseUrl) {
+		this.baseUrl = baseUrl;
+	}
+
+	public void setUrlContext(String urlContext) {
+		this.urlContext = urlContext;
+	}
+
+	public void setUrl(String url) {
+		this.url = url;
+	}
+
+	public void setWebUrl(String webUrl) {
+		this.webUrl = webUrl;
+	}
+
+	public void setCreatedDate(Date createdDate) {
+		this.createdDate = createdDate;
+	}
+
+	public void setLastModified(Date lastModified) {
+		this.lastModified = lastModified;
+	}
+
+	public void setType(PageType type) {
+		this.type = type;
+	}
+
+	public void setTitle(String title) {
+		this.title = title;
+	}
+
+	public void setVersion(int version) {
+		this.version = version;
+	}
+
+	public void setCreator(String creator) {
+		this.creator = creator;
+	}
+
+	public void setCreatorUsername(String creatorUsername) {
+		this.creatorUsername = creatorUsername;
+	}
+
+	public void setLastModifier(String lastModifier) {
+		this.lastModifier = lastModifier;
+	}
+
+	public void setLastModifierUsername(String lastModifierUsername) {
+		this.lastModifierUsername = lastModifierUsername;
+	}
+
+	public void setMediaType(String mediaType) {
+		this.mediaType = mediaType;
+	}
+
+	public void setLength(long length) {
+		this.length = length;
+	}
+
+	public void setContent(String content) {
+		this.content = content;
+	}
+
+	public void setLabels(List<Label> labels) {
+		this.labels = labels;
+	}
+
+}

Added: manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/Page.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/Page.java?rev=1695542&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/Page.java (added)
+++ manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/Page.java Wed Aug 12 14:45:43 2015
@@ -0,0 +1,357 @@
+package org.apache.manifoldcf.crawler.connectors.confluence.model;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.manifoldcf.core.common.DateParser;
+import org.apache.manifoldcf.crawler.connectors.confluence.model.builder.ConfluenceResourceBuilder;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+/**
+ * <p>
+ * Page class
+ * </p>
+ * <p>
+ * Represents a Confluence Page
+ * </p>
+ * 
+ * @author Antonio David Perez Morales <adperezmorales@gmail.com>
+ */
+public class Page extends ConfluenceResource{
+
+	protected static final String KEY_LINKS = "_links";
+	protected static final String KEY_ID = "id";
+	protected static final String KEY_SELF = "self";
+	protected static final String KEY_WEBUI = "webui";
+	protected static final String KEY_BASE = "base";
+	protected static final String KEY_CONTEXT = "context";
+	protected static final String KEY_KEY = "key";
+	protected static final String KEY_TITLE = "title";
+	protected static final String KEY_BODY = "body";
+	protected static final String KEY_VIEW = "view";
+	protected static final String KEY_VALUE = "value";
+	protected static final String KEY_SPACE = "space";
+	protected static final String KEY_HISTORY = "history";
+	protected static final String KEY_CREATED_DATE = "createdDate";
+	protected static final String KEY_CREATED_BY = "createdBy";
+	protected static final String KEY_BY = "by";
+	protected static final String KEY_TYPE = "type";
+	protected static final String KEY_DISPLAY_NAME = "displayName";
+	protected static final String KEY_USER_NAME = "username";
+	protected static final String KEY_VERSION = "version";
+	protected static final String KEY_WHEN = "when";
+	protected static final String KEY_MEDIATYPE = "mediaType";
+
+	private static final String PAGE_ID = "confluenceId";
+	private static final String PAGE_URL = "url";
+	private static final String PAGE_WEBURL = "webUrl";
+	private static final String PAGE_LAST_MODIFIED = "lastModified";
+	private static final String PAGE_CREATOR = "creator";
+	private static final String PAGE_CREATOR_USERNAME = "creatorUsername";
+	private static final String PAGE_LAST_MODIFIER = "lastModifier";
+	private static final String PAGE_LAST_MODIFIER_USERNAME = "lastModifierUsername";
+	private static final String PAGE_SIZE = "size";
+	private static final String PAGE_LABEL = "label";
+
+	protected String id;
+	protected String space;
+	protected String baseUrl;
+	protected String urlContext;
+	protected String url;
+	protected String webUrl;
+	protected Date createdDate;
+	protected Date lastModified;
+	protected PageType type;
+	protected String title;
+	protected int version;
+	protected String creator;
+	protected String creatorUsername;
+	protected String lastModifier;
+	protected String lastModifierUsername;
+	protected String mediaType = "text/html";
+	protected long length;
+	protected String content;
+	protected List<Label> labels = Lists.newArrayList();
+
+	@SuppressWarnings("unused")
+	private JSONObject delegated;
+
+	public Page() {
+
+	}
+
+	public String getContent() {
+		return this.content;
+	}
+
+	public String getId() {
+		return this.id;
+	}
+
+	public PageType getType() {
+		return this.type;
+	}
+
+	public String getMediaType() {
+		return this.mediaType;
+	}
+
+	public int getVersion() {
+		return this.version;
+	}
+
+	public String getTitle() {
+		return this.title;
+	}
+
+	public String getBaseUrl() {
+		return this.baseUrl;
+	}
+
+	public String getUrlContext() {
+		return this.urlContext;
+	}
+
+	public String getWebUrl() {
+		return this.webUrl;
+	}
+
+	public String getUrl() {
+		return this.url;
+	}
+
+	public String getSpace() {
+		return this.space;
+	}
+
+	public String getCreator() {
+		return this.creator;
+	}
+
+	public String getCreatorUsername() {
+		return this.creatorUsername;
+	}
+
+	public String getLastModifier() {
+		return this.lastModifier;
+	}
+
+	public String getLastModifierUsername() {
+		return this.lastModifierUsername;
+	}
+
+	public Date getCreatedDate() {
+		return this.createdDate;
+	}
+
+	public Date getLastModifiedDate() {
+		return this.lastModified;
+	}
+
+	public long getLength() {
+		return this.length;
+	}
+
+	public boolean hasContent() {
+		return this.length > 0 && this.content != null;
+	}
+	
+	public InputStream getContentStream() {
+		String contentStream = content != null ? content : "";
+		return new ByteArrayInputStream(
+				contentStream.getBytes(StandardCharsets.UTF_8));
+	}
+
+	public List<Label> getLabels() {
+		return this.labels;
+	}
+	
+	public Map<String, Object> getMetadataAsMap() {
+		Map<String, Object> pageMetadata = Maps.newHashMap();
+		pageMetadata.put(KEY_ID,  this.id);
+		pageMetadata.put(PAGE_ID, this.id);
+		pageMetadata.put(KEY_TYPE, this.type.toString());
+		pageMetadata.put(KEY_TITLE, this.title);
+		pageMetadata.put(KEY_SPACE, this.space);
+		pageMetadata.put(PAGE_URL, this.url);
+		pageMetadata.put(PAGE_WEBURL, this.webUrl);
+		pageMetadata.put(KEY_CREATED_DATE,
+				DateParser.formatISO8601Date(this.createdDate));
+		pageMetadata.put(PAGE_LAST_MODIFIED,
+				DateParser.formatISO8601Date(this.lastModified));
+		pageMetadata.put(KEY_MEDIATYPE, this.mediaType);
+		pageMetadata.put(KEY_VERSION, String.valueOf(this.version));
+		pageMetadata.put(PAGE_CREATOR, this.creator);
+		pageMetadata.put(PAGE_CREATOR_USERNAME, this.creatorUsername);
+		pageMetadata.put(PAGE_LAST_MODIFIER, this.lastModifier);
+		pageMetadata
+				.put(PAGE_LAST_MODIFIER_USERNAME, this.lastModifierUsername);
+		pageMetadata.put(PAGE_SIZE, String.valueOf(this.length));
+		
+		putLabelsOnMetadataMap(pageMetadata);
+		refineMetadata(pageMetadata);
+		return pageMetadata;
+	}
+
+	/**
+	 * <p>Put the page labels on the metadata map</p>
+	 * @param pageMetadata
+	 */
+	private void putLabelsOnMetadataMap(Map<String, Object> pageMetadata) {
+		if(this.labels == null || this.labels.isEmpty()) {
+			return;
+		}
+		
+		Iterable<String> labelsString = Iterables.transform(this.labels, new Function<Label, String>() {
+			@Override
+			public String apply(Label input) {
+				return input.getName();
+			}
+		});
+		
+		pageMetadata.put(PAGE_LABEL, Lists.newArrayList(labelsString));
+		
+	}
+
+	/**
+	 * <p>
+	 * Used to be overwritten by child classes to add more metadata to the map
+	 * </p>
+	 * 
+	 * @param metadata
+	 */
+	protected void refineMetadata(Map<String, Object> metadata) {
+	}
+
+	public static ConfluenceResourceBuilder<? extends Page> builder() {
+		return new PageBuilder();
+	}
+
+	/**
+	 * <p>PageBuilder internal class</p>
+	 * <p>Used to build pages</p>
+	 * @author Antonio David Perez Morales <adperezmorales@gmail.com>
+	 *
+	 */
+	public static class PageBuilder implements ConfluenceResourceBuilder<Page>{
+		
+		public Page fromJson(JSONObject jsonPage) {
+			return fromJson(jsonPage, new Page());
+		}
+		
+		public Page fromJson(JSONObject jsonPage, Page page) {
+
+			try {
+				String id = jsonPage.getString(KEY_ID);
+				String type = jsonPage.getString(KEY_TYPE);
+				String title = jsonPage.getString(KEY_TITLE);
+
+				page.delegated = jsonPage;
+
+				/* Init Page fields */
+				page.id = id;
+				page.type = PageType.fromName(type);
+				page.title = title;
+
+				page.space = processSpace(jsonPage);
+
+				/*
+				 * Url & WebUrl
+				 */
+				JSONObject links = (JSONObject) jsonPage.get(KEY_LINKS);
+				if (links != null) {
+					page.url = links.optString(KEY_SELF, "");
+					String webUrl = (String) links.optString(KEY_WEBUI, "");
+					page.urlContext = (String) links.optString(KEY_CONTEXT, "");
+					page.baseUrl = (String) links.optString(KEY_BASE, "");
+					page.webUrl = page.baseUrl + page.urlContext + webUrl;
+
+				}
+
+				/*
+				 * Created By and created Date
+				 */
+				JSONObject history = (JSONObject) jsonPage
+						.optJSONObject(KEY_HISTORY);
+				if (history != null) {
+
+					page.createdDate = DateParser.parseISO8601Date(history
+							.optString(KEY_CREATED_DATE, ""));
+					JSONObject createdBy = (JSONObject) history
+							.optJSONObject(KEY_CREATED_BY);
+					if (createdBy != null) {
+						page.creator = createdBy
+								.optString(KEY_DISPLAY_NAME, "");
+						page.creatorUsername = createdBy.optString(
+								KEY_USER_NAME, "");
+					}
+
+				}
+
+				/*
+				 * Last modifier and Last modified date
+				 */
+				JSONObject version = (JSONObject) jsonPage
+						.optJSONObject(KEY_VERSION);
+				if (version != null) {
+					JSONObject by = version.getJSONObject(KEY_BY);
+					if (by != null) {
+						page.lastModifier = by.optString(KEY_DISPLAY_NAME);
+						page.lastModifierUsername = by.optString(KEY_USER_NAME,
+								"");
+					}
+
+					page.lastModified = DateParser.parseISO8601Date(version
+							.optString(KEY_WHEN, ""));
+				}
+
+				/*
+				 * Page Content
+				 */
+				JSONObject body = (JSONObject) jsonPage.optJSONObject(KEY_BODY);
+				if (body != null) {
+					JSONObject view = (JSONObject) body.optJSONObject(KEY_VIEW);
+					if (view != null) {
+						page.content = view.optString(KEY_VALUE, null);
+						page.length = page.content.getBytes().length;
+					}
+				}
+
+				return page;
+
+			} catch (JSONException e) {
+				e.printStackTrace();
+			}
+
+			return new Page();
+
+		}
+
+		private static String processSpace(JSONObject page) {
+			/* Page */
+			try {
+				JSONObject space = (JSONObject) page.get(KEY_SPACE);
+				if (space != null)
+					return space.optString(KEY_KEY, "");
+			} catch (JSONException e) {
+				return "";
+			}
+			return "";
+		}
+
+		@Override
+		public Class<Page> getType() {
+			return Page.class;
+		}
+	}
+}

Added: manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/PageType.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/PageType.java?rev=1695542&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/PageType.java (added)
+++ manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/PageType.java Wed Aug 12 14:45:43 2015
@@ -0,0 +1,29 @@
+package org.apache.manifoldcf.crawler.connectors.confluence.model;
+
+import org.apache.commons.lang.WordUtils;
+
+/**
+ * <p>PageType class</p>
+ * <p>Represents the kind of pages we can have in Confluence</p>
+ * 
+ * @author Antonio David Perez Morales <adperezmorales@gmail.com>
+ *
+ */
+public enum PageType {
+
+	PAGE, ATTACHMENT;
+	
+	public static PageType fromName(String type) {
+		for(PageType pageType: values()) {
+			if(pageType.name().equalsIgnoreCase(type)) {
+				return pageType;
+			}
+		}
+		
+		return PageType.PAGE;
+	}
+	
+	public String toString() {
+		return WordUtils.capitalize(name().toLowerCase());
+	}
+}

Added: manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/Space.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/Space.java?rev=1695542&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/Space.java (added)
+++ manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/Space.java Wed Aug 12 14:45:43 2015
@@ -0,0 +1,55 @@
+package org.apache.manifoldcf.crawler.connectors.confluence.model;
+
+import org.json.JSONObject;
+
+public class Space {
+
+	private static final String KEY_NAME = "name";
+	private static final String KEY_KEY = "key";
+	private static final String KEY_TYPE = "type";
+	private static final String KEY_URL = "url";
+	
+	private String key;
+	private String name;
+	private String type;
+	private String url;
+	
+	public Space() {
+		
+	}
+	
+	public String getKey() {
+		return key;
+	}
+	public void setKey(String key) {
+		this.key = key;
+	}
+	public String getName() {
+		return name;
+	}
+	public void setName(String name) {
+		this.name = name;
+	}
+	public String getType() {
+		return type;
+	}
+	public void setType(String type) {
+		this.type = type;
+	}
+	public String getUrl() {
+		return url;
+	}
+	public void setUrl(String url) {
+		this.url = url;
+	}
+	
+	public static Space fromJson(JSONObject spaceJson) {
+		Space space = new Space();
+		space.key = spaceJson.optString(KEY_KEY, "");
+		space.name = spaceJson.optString(KEY_NAME, "");
+		space.type = spaceJson.optString(KEY_TYPE, "");
+		space.url = spaceJson.optString(KEY_URL, "");
+		return space;
+	}
+	
+}

Added: manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/Spaces.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/Spaces.java?rev=1695542&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/Spaces.java (added)
+++ manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/Spaces.java Wed Aug 12 14:45:43 2015
@@ -0,0 +1,37 @@
+package org.apache.manifoldcf.crawler.connectors.confluence.model;
+
+import java.util.ArrayList;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Spaces extends ArrayList<Space> {
+
+	private static Logger logger = LoggerFactory.getLogger(Spaces.class);
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -5334215263162816914L;
+
+	
+	public static Spaces fromJson(JSONArray jsonSpaces) {
+		Spaces spaces = new Spaces();
+		for(int i=0,len=jsonSpaces.length();i<len;i++) {
+			try {
+				JSONObject spaceJson = jsonSpaces.getJSONObject(i);
+				Space space = Space.fromJson(spaceJson);
+				spaces.add(space);
+			} catch (JSONException e) {
+				logger.debug("Error obtaining JSON item from spaces. Item {} is not a JSON Object", i);
+				e.printStackTrace();
+				continue;
+			}
+		}
+		
+		return spaces;
+		
+	}
+}

Added: manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/builder/ConfluenceResourceBuilder.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/builder/ConfluenceResourceBuilder.java?rev=1695542&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/builder/ConfluenceResourceBuilder.java (added)
+++ manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/model/builder/ConfluenceResourceBuilder.java Wed Aug 12 14:45:43 2015
@@ -0,0 +1,33 @@
+package org.apache.manifoldcf.crawler.connectors.confluence.model.builder;
+
+import org.apache.manifoldcf.crawler.connectors.confluence.model.ConfluenceResource;
+import org.json.JSONObject;
+
+/**
+ * <p>ConfluenceResourceBuilder interface</p>
+ * @author Antonio David Perez Morales <adperezmorales@gmail.com>
+ *
+ * @param <T> Subtype of ConfluenceResource to be built
+ */
+public interface ConfluenceResourceBuilder<T extends ConfluenceResource> {
+
+	/**
+	 * <p>Creates a <T> instance from a JSON representation 
+	 * @param jsonDocument
+	 * @return T instance
+	 */
+	T fromJson(JSONObject jsonDocument);
+	
+	/**
+	 * <p>Populates the given <T> instance from a JSON representation and return it</p>
+	 * @param jsonDocument
+	 * @return T instance
+	 */
+	T fromJson(JSONObject jsonDocument, T document);
+	
+	/**
+	 * <p>Returns the Class of the resource that can be built</p>
+	 * @return the type Class<T> of the resource which can be built by this builder
+	 */
+	Class<T> getType();
+}

Added: manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/util/ConfluenceUtil.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/util/ConfluenceUtil.java?rev=1695542&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/util/ConfluenceUtil.java (added)
+++ manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/confluence/util/ConfluenceUtil.java Wed Aug 12 14:45:43 2015
@@ -0,0 +1,42 @@
+package org.apache.manifoldcf.crawler.connectors.confluence.util;
+
+/**
+ * <p>Utility class for Confluence connectors</p>
+ * 
+ * @author Antonio David Perez Morales <adperezmorales@gmail.com>
+ *
+ */
+public class ConfluenceUtil {
+
+	private static final String ATTACHMENT_ID_PREFIX = "att";
+	
+	/**
+	 * <p>Generates a repository document identifier for the specific attachment and page to be used for Repository Documents for attachment pages</p>
+	 * @param attachmentId
+	 * @param pageId
+	 * @return a generated 
+	 */
+	public static String generateRepositoryDocumentIdentifier(String attachmentId, String pageId) {
+		StringBuilder sb = new StringBuilder();
+		sb.append(attachmentId).append("-").append(pageId);
+		return sb.toString();
+	}
+	
+	/**
+	 * <p>Checks if the given id is an attachment or not</p>
+	 * @param id
+	 * @return a {@code Boolean} indicating if the id is related to an attachment or not 
+	 */
+	public static Boolean isAttachment(String id) {
+		return id.startsWith(ATTACHMENT_ID_PREFIX);
+	}
+	
+	/**
+	 * <p>Gets the attachment id and page id from a repository document id</p>
+	 * @param id the repository document id
+	 * @return an Array containing the attachment and page ids where index 0 is the attachment id and index 1 is the page id
+	 */
+	public static String[] getAttachmentAndPageId(String id) {
+		return id.split("-");
+	}
+}

Added: manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/authorities/confluence/common_en_US.properties
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/authorities/confluence/common_en_US.properties?rev=1695542&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/authorities/confluence/common_en_US.properties (added)
+++ manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/authorities/confluence/common_en_US.properties Wed Aug 12 14:45:43 2015
@@ -0,0 +1,29 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+ConfluenceAuthorityConnector.Server=Server
+
+ConfluenceAuthorityConnector.ProtocolColon=Protocol:
+ConfluenceAuthorityConnector.HostColon=Host:
+ConfluenceAuthorityConnector.PortColon=Port:
+ConfluenceAuthorityConnector.PathColon=Path:
+ConfluenceAuthorityConnector.UsernameColon=Username:
+ConfluenceAuthorityConnector.PasswordColon=Password:
+
+ConfluenceAuthorityConnector.HostMustNotBeNull=Confluence host must not be null
+ConfluenceAuthorityConnector.HostMustNotIncludeSlash=Confluence host must not include a '/' character
+ConfluenceAuthorityConnector.PortMustBeAnInteger=Confluence port must be an integer
+ConfluenceAuthorityConnector.PathMustNotBeNull=Confluence path must not be null
+ConfluenceAuthorityConnector.PathMustBeginWithASlash=Confluence path must begin with a '/' character

Added: manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/confluence/common_en_US.properties
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/confluence/common_en_US.properties?rev=1695542&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/confluence/common_en_US.properties (added)
+++ manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/confluence/common_en_US.properties Wed Aug 12 14:45:43 2015
@@ -0,0 +1,42 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+ConfluenceRepositoryConnector.Server=Server
+ConfluenceRepositoryConnector.Spaces=Spaces
+ConfluenceRepositoryConnector.Pages=Pages
+
+
+ConfluenceRepositoryConnector.ProtocolColon=Protocol:
+ConfluenceRepositoryConnector.HostColon=Host:
+ConfluenceRepositoryConnector.PortColon=Port:
+ConfluenceRepositoryConnector.PathColon=Path:
+ConfluenceRepositoryConnector.UsernameColon=Username:
+ConfluenceRepositoryConnector.PasswordColon=Password:
+
+ConfluenceRepositoryConnector.HostMustNotBeNull=Confluence host must not be null
+ConfluenceRepositoryConnector.HostMustNotIncludeSlash=Confluence host must not include a '/' character
+ConfluenceRepositoryConnector.PortMustBeAnInteger=Confluence port must be an integer
+ConfluenceRepositoryConnector.PathMustNotBeNull=Confluence path must not be null
+ConfluenceRepositoryConnector.PathMustBeginWithASlash=Confluence path must begin with a '/' character
+
+ConfluenceRepositoryConnector.NoSpacesConfigured=No spaces configured. All spaces will be crawled
+
+ConfluenceRepositoryConnector.Add=Add
+ConfluenceRepositoryConnector.AddSpace=Add Space
+ConfluenceRepositoryConnector.Delete=Delete
+ConfluenceRepositoryConnector.DeleteSpace=Delete space #
+ConfluenceRepositoryConnector.TypeInASpace=Type in a space
+
+ConfluenceRepositoryConnector.ProcessAttachments=Process Attachments
\ No newline at end of file

Added: manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/confluence/editConfiguration_conf.js
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/confluence/editConfiguration_conf.js?rev=1695542&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/confluence/editConfiguration_conf.js (added)
+++ manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/confluence/editConfiguration_conf.js Wed Aug 12 14:45:43 2015
@@ -0,0 +1,76 @@
+
+<script type="text/javascript">
+<!--
+function checkConfig()
+{
+  if (editconnection.confluence_port.value != "" && !isInteger(editconnection.confluence_port.value))
+  {
+    alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.ConfPortMustBeAnInteger'))");
+    editconnection.confluence_port.focus();
+    return false;
+  }
+
+  if (editconnection.confluence_host.value != "" && editconnection.confluence_host.value.indexOf("/") != -1)
+  {
+    alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.HostMustNotIncludeSlash'))");
+    editconnection.confluence_host.focus();
+    return false;
+  }
+
+  if (editconnection.confluence_path.value != "" && !(editconnection.confluence_path.value.indexOf("/") == 0))
+  {
+    alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.PathMustBeginWithASlash'))");
+    editconnection.confluence_path.focus();
+    return false;
+  }
+
+  return true;
+}
+ 
+function checkConfigForSave()
+{
+    
+  if (editconnection.confluence_host.value == "")
+  {
+    alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.HostMustNotBeNull'))");
+    SelectTab("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.Server'))");
+    editconnection.confluence_host.focus();
+    return false;
+  }
+  
+  if (editconnection.confluence_host.value != "" && editconnection.confluence_host.value.indexOf("/") != -1)
+  {
+    alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.HostMustNotIncludeSlash'))");
+    SelectTab("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.Server'))");
+    editconnection.confluence_host.focus();
+    return false;
+  }
+
+  if (editconnection.confluence_port.value != "" && !isInteger(editconnection.confluence_port.value))
+  {
+    alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.PortMustBeAnInteger'))");
+    SelectTab("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.Server'))");
+    editconnection.confluence_port.focus();
+    return false;
+  }
+
+  if (editconnection.confluence_path.value == "")
+  {
+    alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.PathMustNotBeNull'))");
+    SelectTab("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.Server'))");
+    editconnection.confluence_path.focus();
+    return false;
+  }
+  
+  if (editconnection.confluence_path.value != "" && !(editconnection.confluence_path.value.indexOf("/") == 0))
+  {
+    alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.PathMustBeginWithASlash'))");
+    SelectTab("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.Server'))");
+    editconnection.confluence_path.focus();
+    return false;
+  }
+  
+  return true;
+}
+//-->
+</script>

Added: manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/confluence/editConfiguration_conf_server.html
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/confluence/editConfiguration_conf_server.html?rev=1695542&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/confluence/editConfiguration_conf_server.html (added)
+++ manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/confluence/editConfiguration_conf_server.html Wed Aug 12 14:45:43 2015
@@ -0,0 +1,83 @@
+
+#if($TABNAME == $ResourceBundle.getString('ConfluenceAuthorityConnector.Server'))
+
+<table class="displaytable">
+  <tr><td class="separator" colspan="2"><hr/></td></tr>
+
+  <tr>
+    <td class="description">
+      <nobr>$Encoder.bodyEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.ProtocolColon'))</nobr>
+    </td>
+    <td class="value">
+      <select size="2" name="confluence_protocol"/>
+#if($CONFLUENCE_PROTOCOL == 'http')
+        <option value="http" selected="true">http</option>
+#else
+        <option value="http">http</option>
+#end
+#if($CONFLUENCE_PROTOCOL == 'https')
+        <option value="https" selected="true">https</option>
+#else
+        <option value="https">https</option>
+#end
+      </select>
+    </td>
+  </tr>
+
+  <tr>
+    <td class="description">
+      <nobr>$Encoder.bodyEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.HostColon'))</nobr>
+    </td>
+    <td class="value">
+      <input size="32" type="text" id="confluence_host" name="confluence_host" value="$Encoder.attributeEscape($CONFLUENCE_HOST)" />
+    </td>
+  </tr>
+
+  <tr>
+    <td class="description">
+      <nobr>$Encoder.bodyEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.PortColon'))</nobr>
+    </td>
+    <td class="value">
+      <input size="5" type="text" id="confluence_port" name="confluence_port" value="$Encoder.attributeEscape($CONFLUENCE_PORT)" />
+    </td>
+  </tr>
+
+  <tr>
+    <td class="description">
+      <nobr>$Encoder.bodyEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.PathColon'))</nobr>
+    </td>
+    <td class="value">
+      <input size="32" type="text" id="confluence_path" name="confluence_path" value="$Encoder.attributeEscape($CONFLUENCE_PATH)" />
+    </td>
+  </tr>
+  
+  <tr><td class="separator" colspan="2"><hr/></td></tr>
+  
+  <tr>
+    <td class="description">
+      <nobr>$Encoder.bodyEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.UsernameColon'))</nobr>
+    </td>
+    <td class="value">
+      <input size="16" type="text" id="confluence_username" name="confluence_username" value="$Encoder.attributeEscape($CONFLUENCE_USERNAME)" />
+    </td>
+  </tr>
+  <tr>
+    <td class="description">
+      <nobr>$Encoder.bodyEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.PasswordColon'))</nobr>
+    </td>
+    <td class="value">
+      <input size="16" type="password" id="confluence_password" name="confluence_password" value="$Encoder.attributeEscape($CONFLUENCE_PASSWORD)" />
+    </td>
+  </tr>
+</table>
+
+#else
+
+<input type="hidden" name="confluence_protocol" value="$Encoder.attributeEscape($CONFLUENCE_PROTOCOL)" />
+<input type="hidden" name="confluence_host" value="$Encoder.attributeEscape($CONFLUENCE_HOST)" />
+<input type="hidden" name="confluence_port" value="$Encoder.attributeEscape($CONFLUENCE_PORT)" />
+<input type="hidden" name="confluence_path" value="$Encoder.attributeEscape($CONFLUENCE_PATH)" />
+<input type="hidden" name="confluence_username" value="$Encoder.attributeEscape($CONFLUENCE_USERNAME)" />
+<input type="hidden" name="confluence_password" value="$Encoder.attributeEscape($CONFLUENCE_PASSWORD)" />
+
+#end

Added: manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/confluence/viewConfiguration_conf.html
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/confluence/viewConfiguration_conf.html?rev=1695542&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/confluence/viewConfiguration_conf.html (added)
+++ manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/confluence/viewConfiguration_conf.html Wed Aug 12 14:45:43 2015
@@ -0,0 +1,62 @@
+
+
+<table class="displaytable">
+
+  <tr>
+    <td class="description">
+      <nobr>$Encoder.bodyEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.ProtocolColon'))</nobr>
+    </td>
+    <td class="value">
+      <nobr>$Encoder.bodyEscape($CONFLUENCE_PROTOCOL)</nobr>
+    </td>
+  </tr>
+
+  <tr>
+    <td class="description">
+      <nobr>$Encoder.bodyEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.HostColon'))</nobr>
+    </td>
+    <td class="value">
+      <nobr>$Encoder.bodyEscape($CONFLUENCE_HOST)</nobr>
+    </td>
+  </tr>
+
+  <tr>
+    <td class="description">
+      <nobr>$Encoder.bodyEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.PortColon'))</nobr>
+    </td>
+    <td class="value">
+      <nobr>$Encoder.bodyEscape($CONFLUENCE_PORT)</nobr>
+    </td>
+  </tr>
+
+  <tr>
+    <td class="description">
+      <nobr>$Encoder.bodyEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.PathColon'))</nobr>
+    </td>
+    <td class="value">
+      <nobr>$Encoder.bodyEscape($CONFLUENCE_PATH)</nobr>
+    </td>
+  </tr>
+
+  <tr><td class="separator" colspan="2"><hr/></td></tr>
+
+  <tr>
+    <td class="description">
+      <nobr>$Encoder.bodyEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.UsernameColon'))</nobr>
+    </td>
+    <td class="value">
+      <nobr>$Encoder.bodyEscape($CONFLUENCE_USERNAME)</nobr>
+    </td>
+  </tr>
+
+  <tr>
+    <td class="description">
+      <nobr>$Encoder.bodyEscape($ResourceBundle.getString('ConfluenceAuthorityConnector.PasswordColon'))</nobr>
+    </td>
+    <td class="value">
+      <nobr>********</nobr>
+    </td>
+  </tr>
+
+</table>
+

Added: manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/resources/org/apache/manifoldcf/crawler/connectors/confluence/editConfiguration_conf.js
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/resources/org/apache/manifoldcf/crawler/connectors/confluence/editConfiguration_conf.js?rev=1695542&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/resources/org/apache/manifoldcf/crawler/connectors/confluence/editConfiguration_conf.js (added)
+++ manifoldcf/branches/CONNECTORS-1161/connectors/confluence/connector/src/main/resources/org/apache/manifoldcf/crawler/connectors/confluence/editConfiguration_conf.js Wed Aug 12 14:45:43 2015
@@ -0,0 +1,76 @@
+
+<script type="text/javascript">
+<!--
+function checkConfig()
+{
+  if (editconnection.confluence_port.value != "" && !isInteger(editconnection.confluence_port.value))
+  {
+    alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceRepositoryConnector.ConfPortMustBeAnInteger'))");
+    editconnection.confluence_port.focus();
+    return false;
+  }
+
+  if (editconnection.confluence_host.value != "" && editconnection.confluence_host.value.indexOf("/") != -1)
+  {
+    alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceRepositoryConnector.HostMustNotIncludeSlash'))");
+    editconnection.confluence_host.focus();
+    return false;
+  }
+
+//  if (editconnection.confluence_path.value != "" && !(editconnection.confluence_path.value.indexOf("/") == 0))
+//  {
+//    alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceRepositoryConnector.PathMustBeginWithASlash'))");
+//    editconnection.confluence_path.focus();
+//    return false;
+//  }
+
+  return true;
+}
+ 
+function checkConfigForSave()
+{
+    
+  if (editconnection.confluence_host.value == "")
+  {
+    alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceRepositoryConnector.HostMustNotBeNull'))");
+    SelectTab("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceRepositoryConnector.Server'))");
+    editconnection.confluence_host.focus();
+    return false;
+  }
+  
+  if (editconnection.confluence_host.value != "" && editconnection.confluence_host.value.indexOf("/") != -1)
+  {
+    alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceRepositoryConnector.HostMustNotIncludeSlash'))");
+    SelectTab("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceRepositoryConnector.Server'))");
+    editconnection.confluence_host.focus();
+    return false;
+  }
+
+  if (editconnection.confluence_port.value != "" && !isInteger(editconnection.confluence_port.value))
+  {
+    alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceRepositoryConnector.PortMustBeAnInteger'))");
+    SelectTab("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceRepositoryConnector.Server'))");
+    editconnection.confluence_port.focus();
+    return false;
+  }
+
+//  if (editconnection.confluence_path.value == "")
+//  {
+//    alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceRepositoryConnector.PathMustNotBeNull'))");
+//    SelectTab("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceRepositoryConnector.Server'))");
+//    editconnection.confluence_path.focus();
+//    return false;
+//  }
+//  
+//  if (editconnection.confluence_path.value != "" && !(editconnection.confluence_path.value.indexOf("/") == 0))
+//  {
+//    alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceRepositoryConnector.PathMustBeginWithASlash'))");
+//    SelectTab("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('ConfluenceRepositoryConnector.Server'))");
+//    editconnection.confluence_path.focus();
+//    return false;
+//  }
+  
+  return true;
+}
+//-->
+</script>



Mime
View raw message