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 <[email protected]> + * + */ +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 <[email protected]> + * + */ +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 <[email protected]> + */ +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 <[email protected]> + * + */ + 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 <[email protected]> + * + */ +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 <[email protected]> + * + */ +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 <[email protected]> + */ +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 <[email protected]> + * + */ + 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 <[email protected]> + */ +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 <[email protected]> + */ +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 <[email protected]> + */ +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 <[email protected]> + * + */ + 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 <[email protected]> + * + */ +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 <[email protected]> + * + * @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 <[email protected]> + * + */ +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>
