com.googlecode.sardine.util.SardineUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.googlecode.sardine.util.SardineUtil.java

Source

//
// Copyright (C) 2010-2016 Roger Rene Kommer & Micromata GmbH
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

package com.googlecode.sardine.util;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;

import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.entity.StringEntity;
import org.w3c.dom.Element;

import com.googlecode.sardine.model.Multistatus;

/**
 * Basic utility code. I borrowed some code from the webdavlib for
 * parsing dates.
 *
 * @author jonstevens
 */
public class SardineUtil {
    /** cached version of getResources() webdav xml GET request */
    private static StringEntity GET_RESOURCES = null;

    /**
     * Date formats using for Date parsing.
     */
    static final SimpleDateFormat formats[] = { new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US),
            new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),
            new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sss'Z'", Locale.US),
            new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US),
            new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US),
            new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
            new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US) };

    /**
     * GMT timezone.
     */
    final static TimeZone gmtZone = TimeZone.getTimeZone("GMT");

    static {
        for (SimpleDateFormat format : formats) {
            format.setTimeZone(gmtZone);
        }
    }

    /**
     * Hides the irritating declared exception.
     */
    public static String encode(String value) {
        try {
            return URLEncoder.encode(value, "utf-8");
        } catch (UnsupportedEncodingException ex) {
            throw new RuntimeException(ex);
        }
    }

    /**
     * Hides the irritating declared exception.
     * @return null if there is an IllegalArgumentException
     * @throws RuntimeException if there is an UnsupportedEncodingException
     */
    public static String decode(String value) {
        try {
            return URLDecoder.decode(value, "utf-8");
        } catch (UnsupportedEncodingException ex) {
            throw new RuntimeException(ex);
        } catch (IllegalArgumentException ex) {
            return null;
        }
    }

    /**
     * Loops over all the possible date formats and tries to find the right one.
     * @param dateValue
     */
    public static Date parseDate(String dateValue) {
        if (dateValue == null)
            return null;

        Date date = null;
        for (int i = 0; (date == null) && (i < formats.length); i++) {
            try {
                synchronized (formats[i]) {
                    date = formats[i].parse(dateValue);
                }
            } catch (ParseException e) {
            }
        }

        return date;
    }

    /**
     * Simple class for making propfind a bit easier to deal with.
     */
    public static class HttpPropFind extends HttpEntityEnclosingRequestBase {
        public HttpPropFind(String url) {
            super();
            this.setDepth(1);
            this.setURI(URI.create(url));
            this.setHeader("Content-Type", "text/xml");
        }

        @Override
        public String getMethod() {
            return "PROPFIND";
        }

        public void setDepth(int val) {
            this.setHeader("Depth", String.valueOf(val));
        }
    }

    /**
     * Simple class for making proppatch a bit easier to deal with.
     */
    public static class HttpPropPatch extends HttpEntityEnclosingRequestBase {
        public HttpPropPatch(String url) {
            super();
            this.setURI(URI.create(url));
            this.setHeader("Content-Type", "text/xml");
        }

        @Override
        public String getMethod() {
            return "PROPPATCH";
        }
    }

    /**
     * Simple class for making move a bit easier to deal with.
     */
    public static class HttpMove extends HttpEntityEnclosingRequestBase {
        public HttpMove(String sourceUrl, String destinationUrl) throws SardineException {
            super();
            this.setHeader("Destination", destinationUrl);
            this.setHeader("Overwrite", "T");
            this.setURI(URI.create(sourceUrl));

            if (sourceUrl.endsWith("/") && !destinationUrl.endsWith("/"))
                throw new SardineException("Destinationurl must end with a /", destinationUrl);
        }

        @Override
        public String getMethod() {
            return "MOVE";
        }
    }

    /**
     * Simple class for making copy a bit easier to deal with. Assumes Overwrite = T.
     */
    public static class HttpCopy extends HttpEntityEnclosingRequestBase {
        public HttpCopy(String sourceUrl, String destinationUrl) throws SardineException {
            super();
            this.setHeader("Destination", destinationUrl);
            this.setHeader("Overwrite", "T");
            this.setURI(URI.create(sourceUrl));

            if (sourceUrl.endsWith("/") && !destinationUrl.endsWith("/"))
                throw new SardineException("Destinationurl must end with a /", destinationUrl);
        }

        @Override
        public String getMethod() {
            return "COPY";
        }
    }

    /**
     * Simple class for making mkcol a bit easier to deal with.
     */
    public static class HttpMkCol extends HttpEntityEnclosingRequestBase {
        public HttpMkCol(String url) {
            super();
            this.setURI(URI.create(url));
        }

        @Override
        public String getMethod() {
            return "MKCOL";
        }
    }

    /**
     * Is the status code 2xx
     */
    public static boolean isGoodResponse(int statusCode) {
        return ((statusCode >= 200) && (statusCode <= 299));
    }

    /**
     * Stupid wrapper cause it needs to be in a try/catch
     */
    public static StringEntity getResourcesEntity() {
        if (GET_RESOURCES == null) {
            try {
                GET_RESOURCES = new StringEntity("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
                        + "<propfind xmlns=\"DAV:\">\n" + "   <allprop/>\n" + "</propfind>", "UTF-8");
            } catch (UnsupportedEncodingException e) {
                // Ignored
            }
        }

        return GET_RESOURCES;
    }

    /**
     * Build PROPPATCH entity.
     */
    public static StringEntity getResourcePatchEntity(Map<String, String> setProps, List<String> removeProps) {
        StringEntity patchEntity = null;

        try {
            StringBuffer buf = new StringBuffer("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n");
            buf.append("<D:propertyupdate xmlns:D=\"DAV:\" xmlns:S=\"SAR:\">\n");

            if (setProps != null) {
                buf.append("<D:set>\n");
                buf.append("<D:prop>\n");
                for (Map.Entry<String, String> prop : setProps.entrySet()) {
                    buf.append("<S:");
                    buf.append(prop.getKey()).append(">");
                    buf.append(prop.getValue()).append("</S:");
                    buf.append(prop.getKey()).append(">\n");
                }
                buf.append("</D:prop>\n");
                buf.append("</D:set>\n");
            }

            if (removeProps != null) {
                buf.append("<D:remove>\n");
                buf.append("<D:prop>\n");
                for (String removeProp : removeProps) {
                    buf.append("<S:");
                    buf.append(removeProp).append("/>");
                }
                buf.append("</D:prop>\n");
                buf.append("</D:remove>\n");
            }

            buf.append("</D:propertyupdate>\n");

            patchEntity = new StringEntity(buf.toString());

        } catch (UnsupportedEncodingException e) {
            // Ignored
        }

        return patchEntity;
    }

    /**
     * Helper method for getting the Multistatus response processor.
     */
    public static Multistatus getMulitstatus(Unmarshaller unmarshaller, HttpResponse response, String url)
            throws SardineException {
        try {
            return (Multistatus) unmarshaller.unmarshal(response.getEntity().getContent());
        } catch (JAXBException ex) {
            throw new SardineException("Problem unmarshalling the data", url, ex);
        } catch (IOException ex) {
            throw new SardineException(ex);
        }
    }

    /** */
    public static Map<String, String> extractCustomProps(List<Element> elements) {
        Map<String, String> customPropsMap = new HashMap<String, String>(elements.size());

        for (Element element : elements) {
            String[] keys = element.getTagName().split(":", 2);
            String key = (keys.length > 1) ? keys[1] : keys[0];

            customPropsMap.put(key, element.getTextContent());
        }

        return customPropsMap;
    }

}