com.smartitengineering.util.opensearch.io.impl.dom.OpenSearchDescriptorWriter.java Source code

Java tutorial

Introduction

Here is the source code for com.smartitengineering.util.opensearch.io.impl.dom.OpenSearchDescriptorWriter.java

Source

/*
 * This is a utility project for wide range of applications
 *
 * Copyright (C) 2010  Imran M Yousuf (imyousuf@smartitengineering.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 * This library 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
 * Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  10-1  USA
 */
package com.smartitengineering.util.opensearch.io.impl.dom;

import com.smartitengineering.util.opensearch.api.Image;
import com.smartitengineering.util.opensearch.api.OpenSearchDescriptor;
import com.smartitengineering.util.opensearch.api.Query;
import com.smartitengineering.util.opensearch.api.Url;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collection;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import nu.xom.Attribute;
import nu.xom.Document;
import nu.xom.Element;
import nu.xom.Node;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;

/**
 *
 * @author imyousuf
 */
class OpenSearchDescriptorWriter implements XmlConstants {

    private OutputStream sink;
    private OpenSearchDescriptor descriptor;
    private boolean closeOnFinish;
    private final Map<String, String> namespaceUris;

    OpenSearchDescriptorWriter(OutputStream sink, OpenSearchDescriptor descriptor) {
        this(sink, descriptor, false);
    }

    OpenSearchDescriptorWriter(OutputStream sink, OpenSearchDescriptor descriptor, boolean closeOnFinish) {
        if (sink == null) {
            throw new IllegalArgumentException("Source stream can not be null!");
        }
        if (descriptor == null) {
            throw new IllegalArgumentException("Descriptor can not be null!");
        }
        this.descriptor = descriptor;
        this.sink = sink;
        this.closeOnFinish = closeOnFinish;
        this.namespaceUris = new HashMap<String, String>();
    }

    public void write() throws IOException {
        try {
            final Document document;
            document = buildDoc();
            IOUtils.write(document.toXML(), sink);
        } finally {
            if (closeOnFinish) {
                try {
                    sink.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }

    protected Document buildDoc() {
        Element rootElement = getOpenSearchElement(ELEM_OPENSEARCHDESCRIPTION);
        addStringElement(rootElement, ELEM_SHORTNAME, descriptor.getShortName());
        addStringElement(rootElement, ELEM_DESCRIPTION, descriptor.getDescription());
        addCollectionOfStringAsSpaceDelimitedStringTextElement(descriptor.getTags(), ELEM_TAGS, rootElement);
        addStringElement(rootElement, ELEM_CONTACT, descriptor.getContact());
        for (Url url : descriptor.getUrls()) {
            addUrlElement(url, rootElement);
        }
        addStringElement(rootElement, ELEM_LONGNAME, descriptor.getLongName());
        for (Image image : descriptor.getImages()) {
            addImageElement(image, rootElement);
        }
        for (Query query : descriptor.getQueries()) {
            addQueryElement(query, rootElement);
        }
        addStringElement(rootElement, ELEM_DEVELOPER, descriptor.getDeveloper());
        addStringElement(rootElement, ELEM_ATTRIBUTION, descriptor.getAttribution());
        addStringElement(rootElement, ELEM_SYNDICATIONRIGHT, descriptor.getSyndicationRight().getValue());
        addStringElement(rootElement, ELEM_ADULTCONTENT, Boolean.toString(descriptor.containsAdultContent()));
        addStringElement(rootElement, ELEM_LANGUAGE, getLocaleString(descriptor.getLanguage()));
        addStringElement(rootElement, ELEM_OUTPUTENCODING, descriptor.getOutputEncoding());
        addStringElement(rootElement, ELEM_INPUTENCODING, descriptor.getInputEncoding());
        return new Document(rootElement);
    }

    protected String getCollectionOfStringAsSpaceDelimitedString(final Collection<? extends Object> objs) {
        final String singleString;
        if (!objs.isEmpty()) {
            final StringBuilder stringBuilder = new StringBuilder("");
            boolean first = true;
            for (Object obj : objs) {
                if (obj == null) {
                    continue;
                }
                String objStr = obj.toString();
                if (StringUtils.isNotBlank(objStr)) {
                    if (!first) {
                        stringBuilder.append(' ');
                    }
                    stringBuilder.append(objStr);
                    first = false;
                }
            }
            singleString = stringBuilder.toString();
        } else {
            singleString = null;
        }
        return singleString;
    }

    protected Element addCollectionOfStringAsSpaceDelimitedStringTextElement(
            final Collection<? extends Object> objs, String childElementName, Element parentElement) {
        String tagString = getCollectionOfStringAsSpaceDelimitedString(objs);
        return addStringElement(parentElement, childElementName, tagString);
    }

    protected Node addCollectionOfStringAsSpaceDelimitedStringAttributed(final Collection<? extends Object> objs,
            String childAttrName, Element parentElement) {
        String attrValue = getCollectionOfStringAsSpaceDelimitedString(objs);
        return addStringAttr(parentElement, childAttrName, attrValue);
    }

    protected Element addStringElement(Element parentElement, String childElementName, String value) {
        if (StringUtils.isNotBlank(value)) {
            Element childElement = getOpenSearchElement(childElementName);
            parentElement.appendChild(childElement);
            childElement.appendChild(value);
            return childElement;
        }
        return null;
    }

    protected Node addStringAttr(Element parentElement, String childAttrName, int value, int min) {
        if (value > min) {
            return addStringAttr(parentElement, childAttrName, value);
        } else {
            return null;
        }
    }

    protected Node addStringAttr(Element parentElement, String childAttrName, int value) {
        return addStringAttr(parentElement, childAttrName, Integer.toString(value));
    }

    protected Node addStringAttr(Element parentElement, String childAttrName, String value) {
        if (StringUtils.isNotBlank(value)) {
            final int indexOf = childAttrName.indexOf(':');
            final boolean isNamespace;
            final String ns;
            final String prefix;
            if (indexOf > 0) {
                ns = childAttrName.substring(0, indexOf);
                if (StringUtils.equals("xmlns", ns)) {
                    isNamespace = true;
                } else {
                    isNamespace = false;
                }
                prefix = childAttrName.substring(indexOf + 1);
            } else {
                ns = "";
                isNamespace = false;
                prefix = "";
            }
            if (isNamespace) {
                namespaceUris.put(prefix, value);
                parentElement.addNamespaceDeclaration(prefix, value);
                return null;
            } else {
                final Attribute childAttribute;
                if (indexOf > 0) {
                    childAttribute = new Attribute(childAttrName, namespaceUris.get(ns), value);
                } else {
                    childAttribute = new Attribute(childAttrName, value);
                }
                parentElement.addAttribute(childAttribute);
                return childAttribute;
            }
        }
        return null;
    }

    protected void addMapAsAttributes(Map<String, String> map, final Element element) {
        for (Map.Entry<String, String> entry : map.entrySet()) {
            addStringAttr(element, entry.getKey(), entry.getValue());
        }
    }

    protected Element addUrlElement(Url url, Element rootElement) {
        final Element urlElement;
        if (url != null) {
            urlElement = getOpenSearchElement(ELEM_URL);
            rootElement.appendChild(urlElement);
            Map<String, String> map = url.getCustomAttributes();
            addMapAsAttributes(map, urlElement);
            addStringAttr(urlElement, ATTR_TEMPLATE, url.getTemplate());
            addStringAttr(urlElement, ATTR_TYPE, url.getType());
            addCollectionOfStringAsSpaceDelimitedStringAttributed(url.getRels(), ATTR_REL, urlElement);
            addStringAttr(urlElement, ATTR_INDEXOFFSET, url.getIndexOffset());
            addStringAttr(urlElement, ATTR_PAGEOFFSET, url.getPageOffset());
        } else {
            urlElement = null;
        }
        return urlElement;
    }

    protected Element addImageElement(Image image, Element rootElement) {
        if (image != null) {
            Element imageElement = addStringElement(rootElement, ELEM_IMAGE, image.getImageUri().toString());
            if (imageElement != null) {
                final int height = image.getHeight();
                if (height > 0) {
                    addStringAttr(imageElement, ATTR_HEIGHT, height);
                }
                final int width = image.getWidth();
                if (width > 0) {
                    addStringAttr(imageElement, ATTR_WIDTH, width);
                }
                addStringAttr(imageElement, ATTR_TYPE, image.getMimeType());
            }
            return imageElement;
        }
        return null;
    }

    protected Element addQueryElement(Query query, Element rootElement) {
        if (query != null) {
            Element queryElement = getOpenSearchElement(ELEM_QUERY);
            addMapAsAttributes(query.getCustomAttributes(), queryElement);
            addStringAttr(queryElement, ATTR_ROLE, query.getRole().getRoleString());
            addStringAttr(queryElement, ATTR_TITLE, query.getTitle());
            addStringAttr(queryElement, ATTR_SEARCHTERMS, query.getSearchTerms());
            addStringAttr(queryElement, ATTR_TOTALRESULTS, query.getTotalResults(), -1);
            addStringAttr(queryElement, ATTR_COUNT, query.getCount(), -1);
            addStringAttr(queryElement, ATTR_STARTINDEX, query.getStartIndex(), -1);
            addStringAttr(queryElement, ATTR_STARTPAGE, query.getStartPage(), -1);
            addStringAttr(queryElement, ATTR_LANGUAGE, query.getLanguage());
            addStringAttr(queryElement, ATTR_INPUTENCODING, query.getInputEncoding());
            addStringAttr(queryElement, ATTR_OUTPUTENCODING, query.getOutputEncoding());
            rootElement.appendChild(queryElement);
            return queryElement;
        }
        return null;
    }

    protected String getLocaleString(Locale language) {
        if (language == null) {
            return null;
        } else {
            StringBuilder localeString = new StringBuilder("");
            if (StringUtils.isNotBlank(language.getLanguage())) {
                localeString.append(language.getLanguage());
                if (StringUtils.isNotBlank(language.getCountry())) {
                    localeString.append('-').append(language.getCountry().toLowerCase());
                }
            }
            return localeString.toString();
        }
    }

    protected Element getOpenSearchElement(String name) {
        return new Element(name, XmlConstants.NS_OPENSEARCH);
    }
}