com.seajas.search.contender.service.modifier.AbstractModifierService.java Source code

Java tutorial

Introduction

Here is the source code for com.seajas.search.contender.service.modifier.AbstractModifierService.java

Source

/**
 * Copyright (C) 2013 Seajas, the Netherlands.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3, as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.seajas.search.contender.service.modifier;

import com.sun.syndication.feed.synd.SyndEnclosure;
import com.sun.syndication.feed.synd.SyndEntry;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.ftp.FTPSClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

/**
 * Modifier service base.
 * 
 * @author Jasper van Veghel <jasper@seajas.com>
 */
public abstract class AbstractModifierService {
    /**
     * The logger.
     */
    private static final Logger logger = LoggerFactory.getLogger(AbstractModifierService.class);

    /**
     * The maximum content length.
     */
    protected Long maximumContentLength;

    /**
     * The preferred enclosures.
     */
    protected List<String> preferredEnclosures;

    /**
     * Default constructor.
     */
    public AbstractModifierService() {
        // Do nothing
    }

    /**
     * Default constructor.
     * 
     * @param maximumContentLength
     * @param preferredEnclosures
     */
    public AbstractModifierService(final Long maximumContentLength, final String preferredEnclosures) {
        this.maximumContentLength = maximumContentLength;
        this.preferredEnclosures = Arrays
                .asList(StringUtils.tokenizeToStringArray(preferredEnclosures, ",", true, true));
    }

    /**
     * Retrieve the FTP client belonging to the given URI.
     * 
     * @param uri
     * @return FTPClient
     */
    protected FTPClient retrieveFtpClient(final URI uri) {
        // Create the FTP client

        FTPClient ftpClient = uri.getScheme().equalsIgnoreCase("ftps") ? new FTPSClient() : new FTPClient();

        try {
            ftpClient.connect(uri.getHost(), uri.getPort() != -1 ? uri.getPort() : 21);

            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                ftpClient.disconnect();

                logger.error("Could not connect to the given FTP server " + uri.getHost()
                        + (uri.getPort() != -1 ? ":" + uri.getPort() : "") + " - " + ftpClient.getReplyString());

                return null;
            }

            if (StringUtils.hasText(uri.getUserInfo())) {
                if (uri.getUserInfo().contains(":"))
                    ftpClient.login(uri.getUserInfo().substring(0, uri.getUserInfo().indexOf(":")),
                            uri.getUserInfo().substring(uri.getUserInfo().indexOf(":") + 1));
                else
                    ftpClient.login(uri.getUserInfo(), "");
            }

            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                ftpClient.disconnect();

                logger.error("Could not login to the given FTP server " + uri.getHost()
                        + (uri.getPort() != -1 ? ":" + uri.getPort() : "") + " - " + ftpClient.getReplyString());

                return null;
            }

            // Switch to PASV and BINARY mode

            ftpClient.enterLocalPassiveMode();
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

            return ftpClient;
        } catch (IOException e) {
            logger.error("Could not close input stream during archive processing", e);
        }

        return null;
    }

    /**
     * Create a StringBuffer out of the given reader content.
     * 
     * @param buffer
     * @param reader
     * @param cleanFromProlog
     * @return Reader
     */
    protected Reader readerToBuffer(final StringBuffer buffer, final Reader reader, final boolean cleanFromProlog) {
        Integer lastProlog = -1;

        try {
            char[] characterBuffer = new char[8192];

            for (int count; (count = reader.read(characterBuffer)) > 0;) {
                buffer.append(characterBuffer, 0, count);

                // When cleaning by prolog, we stop writing out the buffer after the second prolog

                if (cleanFromProlog) {
                    if (lastProlog == -1)
                        lastProlog = buffer.indexOf("<?xml");
                    if (lastProlog != -1 && (lastProlog = buffer.indexOf("<?xml", lastProlog + 1)) != -1) {
                        logger.warn("Input document contains more than one XML prolog. Stripping any extra ones.");

                        buffer.replace(lastProlog, buffer.length(), "");

                        break;
                    }
                }
            }

            reader.close();

            return new StringReader(buffer.toString().trim());
        } catch (IOException e) {
            logger.error("Could not convert the given reader to a buffer", e);

            return null;
        }
    }

    /**
     * Retrieve the proper link from a given entry, taking into account enclosures etc.
     *
     * @param entry
     * @return String
     */
    public String getEntryLink(final SyndEntry entry) {
        String uri = null;

        // Use a preferred enclosure if one is available (and is a valid URI)

        if (entry.getEnclosures().size() > 0 && preferredEnclosures.size() > 0)
            for (SyndEnclosure enclosure : (Collection<SyndEnclosure>) entry.getEnclosures()) {
                for (String preferredEnclosure : preferredEnclosures)
                    if (preferredEnclosure.equals(enclosure.getType())) {
                        try {
                            uri = enclosure.getUrl();

                            new URI(uri);
                        } catch (URISyntaxException e) {
                            uri = null;
                        }

                        break;
                    }
            }

        // Otherwise simply use the link

        if (uri == null)
            uri = getNonPreferentialEntryLink(entry);

        return uri != null ? uri.trim() : uri;
    }

    /**
     * Convenience method to retrieve the SyndEntry link.
     *
     * @param entry
     * @return String
     */
    protected static String getNonPreferentialEntryLink(final SyndEntry entry) {
        return StringUtils.hasText(entry.getLink()) ? entry.getLink() : entry.getUri();
    }
}