org.openehealth.ipf.labs.maven.confluence.export.AbstractConfluenceExportTemplate.java Source code

Java tutorial

Introduction

Here is the source code for org.openehealth.ipf.labs.maven.confluence.export.AbstractConfluenceExportTemplate.java

Source

/*
 * Copyright 2011 the original author or authors.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *     
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.openehealth.ipf.labs.maven.confluence.export;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.rmi.RemoteException;
import java.util.List;

import javax.xml.rpc.ServiceException;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpException;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.maven.plugin.logging.Log;

/**
 * @author Mitko Kolev
 * 
 */
public abstract class AbstractConfluenceExportTemplate {

    protected final URL confluenceBaseUrl;
    protected final String user;
    protected final String password;
    protected final Log log;

    public AbstractConfluenceExportTemplate(URL confluenceBaseUrl, String user, String password, Log log) {
        this.confluenceBaseUrl = confluenceBaseUrl;
        this.user = user;
        this.password = password;
        this.log = log;
    }

    public void export(DefaultHttpClient httpClient, List<ExportSpace> spaces, boolean isVersion30AndAbove,
            File outputFolder) throws IOException, RemoteException, ServiceException, HttpException {
        String sessionId = login(httpClient);

        for (ExportSpace space : spaces) {
            long started = System.currentTimeMillis();
            log.info("Starting a Confluence export for space: " + space);
            log.info("Please wait for the Confluence export process to finish.");
            log.info("This could take a few minutes ...");

            String exportedUrl = export(space, isVersion30AndAbove);
            long finished = System.currentTimeMillis();
            log.info(space.getKey() + " (" + space.getType() + ") -> " + exportedUrl);
            log.info(took("Confluence export process for " + space.getKey(), finished - started));

            String fileName = fileName(exportedUrl, space);
            log.info("Downloading " + exportedUrl);
            long downloadStarted = System.currentTimeMillis();
            File target = new File(outputFolder, fileName);

            store(exportedUrl, httpClient, sessionId, target);
            log.info(took("Downloading " + target.getName(), System.currentTimeMillis() - downloadStarted));
            log.info(space.getKey() + " (" + space.getType() + ") -> " + target.getAbsolutePath());
            log.info("-----------");
        }
        logout(httpClient);
    }

    protected abstract String export(ExportSpace space, boolean isVersion30AndAbove)
            throws RemoteException, javax.xml.rpc.ServiceException;

    public void store(String exportedSpaceUrl, DefaultHttpClient client, String sessionId, File targetFile)
            throws IOException {

        HttpGet get = new HttpGet(exportedSpaceUrl);
        get.addHeader("Cookie", "confluence.browse.space.cookie=space-pages; "
                + "confluence.list.pages.cookie=list-content-tree; " + "JSESSIONID=" + sessionId);
        get.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
        get.addHeader("Accept-Encoding", "gzip, deflate");

        InputStream content = null;
        try {
            HttpResponse httpResponse = client.execute(get);
            content = httpResponse.getEntity().getContent();
            download(content, targetFile);
        } finally {
            IOUtils.closeQuietly(content);
        }
    }

    private void download(InputStream content, File targetFile) throws IOException {
        if (!targetFile.exists()) {
            targetFile.setWritable(true);
            targetFile.getParentFile().mkdirs();
            boolean created = targetFile.createNewFile();
            if (!created) {
                throw new IOException("Unable to create file " + targetFile.getAbsolutePath());
            }
        }
        OutputStream targetStream = null;
        try {
            targetStream = new BufferedOutputStream(new FileOutputStream(targetFile), 1024 * 4);
            IOUtils.copy(content, targetStream);
        } finally {
            IOUtils.closeQuietly(targetStream);
        }
    }

    private String fileName(String exportedUrl, ExportSpace space) {
        if (space.getOutputFileName() == null) {
            String[] splits = exportedUrl.split("/");
            if (splits.length > 0) {
                return splits[splits.length - 1];
            } else {
                throw new IllegalArgumentException("Unable to split the url " + exportedUrl);
            }
        } else {
            return space.getOutputFileName();
        }
    }

    protected String login(DefaultHttpClient client) throws IOException, HttpException {
        HttpPost loginRequest = new HttpPost(confluenceBaseUrl.toExternalForm() + "/login.action");
        HttpResponse response = null;
        try {
            log.debug("Loggin " + user);
            loginRequest.setEntity(buildLoginRequestEntity());
            response = client.execute(loginRequest);
            int statusCode = response.getStatusLine().getStatusCode();
            log.debug("Login finished with status code " + statusCode);
            if (response.getStatusLine().getStatusCode() > 400) {
                throw new HttpException(
                        "Unable to login to Confluence: " + IOUtils.toString(response.getEntity().getContent()));
            }
        } finally {
            if (response != null) {
                IOUtils.closeQuietly(response.getEntity().getContent());
            }
        }
        String seessionId = extractSessionId(client);
        log.debug("Got session id " + seessionId);
        return seessionId;
    }

    protected boolean logout(DefaultHttpClient client) throws IOException {
        HttpGet logoutRequest = new HttpGet(confluenceBaseUrl.toExternalForm() + "/logout.action");
        HttpResponse response = null;
        try {
            log.debug("Logging out " + user);
            response = client.execute(logoutRequest);
            int statusCode = response.getStatusLine().getStatusCode();
            log.debug("Logout finished with status code " + statusCode);
            if (response.getStatusLine().getStatusCode() > 400) {
                return false;
            }
        } finally {
            if (response != null) {
                IOUtils.closeQuietly(response.getEntity().getContent());
            }
        }
        return true;
    }

    /**
     * Extracts the JSESSIONID cookie from the HttpMethod
     * 
     * @param client
     * @return the value of the JSESSIONID cookie
     */
    private String extractSessionId(DefaultHttpClient client) throws HttpException {
        for (org.apache.http.cookie.Cookie cookie : client.getCookieStore().getCookies()) {
            if (cookie.getName().equals("JSESSIONID")) {
                return cookie.getValue();
            }
        }
        throw new HttpException("No JSESSIONID found in Set-Cookie response header.");
    }

    private StringEntity buildLoginRequestEntity() throws UnsupportedEncodingException {
        StringBuilder content = new StringBuilder();
        content.append("os_username=").append(user);
        content.append("&os_password=").append(password);
        content.append("&login=Log+In&os_destination=");
        String contentType = "application/x-www-form-urlencoded";
        String encoding = "UTF-8";
        return new StringEntity(content.toString(), contentType, encoding);
    }

    protected String took(String prefix, long millis) {
        int seconds = (int) (millis / 1000) % 60;
        int minutes = (int) ((millis / (1000 * 60)) % 60);
        int hours = (int) ((millis / (1000 * 60 * 60)) % 24);

        StringBuilder took = new StringBuilder(prefix + " took ");
        if (hours != 0) {
            took.append((hours + "h "));
            took.append((minutes + "min "));
        } else {
            if (minutes != 0) {
                took.append((minutes + "min "));
            }
        }
        took.append(seconds + "seconds");

        return took.toString();
    }

}