org.apache.rave.portal.service.impl.DefaultOmdlService.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.rave.portal.service.impl.DefaultOmdlService.java

Source

/*
 * 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.
 */
package org.apache.rave.portal.service.impl;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.io.FileUtils;
import org.apache.rave.exception.DuplicateItemException;
import org.apache.rave.model.Page;
import org.apache.rave.model.Widget;
import org.apache.rave.portal.model.impl.WidgetImpl;
import org.apache.rave.portal.model.util.omdl.BadOmdlXmlFormatException;
import org.apache.rave.portal.model.util.omdl.OmdlConstants;
import org.apache.rave.portal.model.util.omdl.OmdlInputAdapter;
import org.apache.rave.portal.model.util.omdl.OmdlModelUtils;
import org.apache.rave.portal.model.util.omdl.OmdlOutputAdapter;
import org.apache.rave.portal.model.util.omdl.OmdlWidgetReference;
import org.apache.rave.portal.service.OmdlService;
import org.apache.rave.portal.service.PageService;
import org.apache.rave.portal.service.UserService;
import org.apache.rave.portal.service.RemoteWidgetResolverService;
import org.apache.rave.portal.service.WidgetService;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * This class is responsible for the import and export of page objects to/from OMDL format
 * 
 * See: http://omdl.org 
 * 
 * for more information on the specification.
 */
@Service
public class DefaultOmdlService implements OmdlService, OmdlConstants {

    private static org.slf4j.Logger logger = LoggerFactory.getLogger(DefaultOmdlService.class);

    @Value("${provider.wookie.wookieServerUrl}")
    private String wookieUrl;

    private PageService pageService;
    private WidgetService widgetService;
    private UserService userService;
    private RemoteWidgetResolverService widgetResolverService;

    public DefaultOmdlService() {
    }

    @Autowired
    public DefaultOmdlService(PageService pageService, WidgetService widgetService, UserService userService,
            RemoteWidgetResolverService widgetResolverService) {
        this.pageService = pageService;
        this.widgetService = widgetService;
        this.userService = userService;
        this.widgetResolverService = widgetResolverService;
    }

    @Override
    public OmdlOutputAdapter exportOmdl(String pageId, String omdlUrl) {
        Page page = pageService.getPage(pageId);
        OmdlOutputAdapter omdl = new OmdlOutputAdapter(widgetService, userService);
        omdl.buildModel(page, omdlUrl, wookieUrl);
        return omdl;
    }

    @Override
    public Page importOmdl(MultipartFile multipartFile, String pageName) throws DuplicateItemException {
        Page page = null;
        OmdlInputAdapter omdlInputAdapter = new OmdlInputAdapter();
        File temp = null;
        String xml = null;
        try {
            if (multipartFile != null) {
                if (multipartFile.getSize() > 0) {
                    String tempUploadFolder = System.getProperty("java.io.tmpdir");
                    temp = new File(tempUploadFolder, multipartFile.getOriginalFilename());
                    multipartFile.transferTo(temp);
                    xml = FileUtils.readFileToString(temp);
                }
            }
        } catch (IllegalStateException e) {
            logger.error(e.getMessage());
            throw new RuntimeException(e);
        } catch (IOException e) {
            logger.error(e.getMessage());
            throw new RuntimeException(e);
        }

        Document root = initializeBuilder(xml);
        if (root != null) {
            try {
                parseOmdlFile(root, omdlInputAdapter);
            } catch (BadOmdlXmlFormatException e) {
                logger.error(e.getMessage());
                throw new RuntimeException(e);
            }
        }
        page = pageService.addNewUserPage(pageName, omdlInputAdapter.getLayoutCode());
        switch (page.getRegions().size()) {
        case 1:
            populateRegionWidgets(page, omdlInputAdapter.getAllUrls(), page.getRegions().get(0).getId());
            break;
        case 2:
            populateRegionWidgets(page, omdlInputAdapter.getAllLeftUrls(), page.getRegions().get(0).getId());
            populateRegionWidgets(page, omdlInputAdapter.getAllRightUrls(), page.getRegions().get(1).getId());
            break;
        case 3:
            populateRegionWidgets(page, omdlInputAdapter.getAllLeftUrls(), page.getRegions().get(0).getId());
            populateRegionWidgets(page, omdlInputAdapter.getAllCenterUrls(), page.getRegions().get(1).getId());
            populateRegionWidgets(page, omdlInputAdapter.getAllRightUrls(), page.getRegions().get(2).getId());
            break;
        case 4:
            populateRegionWidgets(page, omdlInputAdapter.getAllLeftUrls(), page.getRegions().get(0).getId());
            populateRegionWidgets(page, omdlInputAdapter.getAllCenterUrls(), page.getRegions().get(1).getId());
            populateRegionWidgets(page, omdlInputAdapter.getAllRightUrls(), page.getRegions().get(2).getId());
            populateRegionWidgets(page, omdlInputAdapter.getAllUnknownUrls(), page.getRegions().get(3).getId());
            break;
        default:
            // there are no layouts with more than 4 regions at present
        }
        return page;
    }

    private void populateRegionWidgets(Page page, List<OmdlWidgetReference> widgetReferences, String regionId) {
        Widget raveWidget = null;
        for (OmdlWidgetReference widgetReference : widgetReferences) {
            // try to find if the widget is already installed in rave by its identifier (should be the rave widget url)
            logger.info("Found OMDL widget reference (" + widgetReference.getWidgetIdentifier() + ")");
            raveWidget = widgetService.getWidgetByUrl(widgetReference.getWidgetIdentifier());

            // If not found download and install to widget container, then to rave.
            if (raveWidget == null) {
                String providerType = widgetReference.getRaveWidgetTypeFromFormatType();
                if (!providerType.equals(null)) {
                    try {
                        Widget resolvedWidget = widgetResolverService
                                .resolveAndDownloadWidgetMetadata(widgetReference.getWidgetLink(), providerType);
                        if (resolvedWidget != null) {
                            // Check again in case the OMDL id attribute is not the same as the one found in the href attribute
                            if (widgetService.getWidgetByUrl(resolvedWidget.getUrl()) == null) {
                                raveWidget = widgetResolverService.addWidget(resolvedWidget);
                                logger.info("Widget added to rave. (" + raveWidget.getUrl() + ")");
                            } else {
                                logger.info("Widget was already added to rave. (" + resolvedWidget.getUrl() + ")");
                            }
                        }
                    } catch (Exception e) {
                        logger.error("Problem installing widget: " + e.getMessage());
                        throw new RuntimeException(e);
                    }
                }
            }

            if (raveWidget != null) {
                if (widgetResolverService.isPublished()) {
                    pageService.addWidgetToPageRegion(page.getId(), raveWidget.getId(), regionId);
                } else {
                    logger.error("Unable to add widget to page as the default status is set to PREVIEW. ("
                            + raveWidget.getUrl() + ")");
                }
            } else {
                logger.error("Unable to resolve widget entry found in OMDL file. "
                        + widgetReference.getWidgetIdentifier() + " : " + widgetReference.getWidgetLink());
            }
        }
    }

    private void parseOmdlFile(Document xml, OmdlInputAdapter omdlInputAdapter) throws BadOmdlXmlFormatException {
        Element rootEl = xml.getDocumentElement();
        String rootNodename = rootEl.getNodeName();
        String namespace = rootEl.getNamespaceURI();
        if (rootNodename != WORKSPACE) {
            throw new BadOmdlXmlFormatException("Root node must be <" + WORKSPACE + ">");
        }
        // TODO - which is it - spec examples show both?
        if (namespace != NAMESPACE && namespace != NAMESPACE + "/") {
            throw new BadOmdlXmlFormatException("Default xml namespace must be " + NAMESPACE);
        }
        //child <identifier> - omit
        //child <goal> - omit
        //child <status> - omit
        //child <description> - omit
        //child <creator> - omit
        //child <date> - omit

        // Try to get the page name (title in omdl)
        String title = null;
        NodeList nodeList = rootEl.getElementsByTagNameNS(namespace, TITLE);
        if (nodeList.getLength() > 0) {
            Node node = rootEl.getElementsByTagNameNS(namespace, TITLE).item(0);
            if (node.getTextContent() != null) {
                title = node.getTextContent();
            }
        }
        // store this if found, although at present it will be overwritten by the users page name
        omdlInputAdapter.setName(title);

        String layoutCode = null;
        // Try to get the layoutCode
        nodeList = rootEl.getElementsByTagNameNS(namespace, LAYOUT);
        if (nodeList.getLength() > 0) {
            Node node = rootEl.getElementsByTagNameNS(namespace, LAYOUT).item(0);
            if (node.getTextContent() != null) {
                layoutCode = node.getTextContent();
            }
        }
        // Next try to find all the <app> elements (widgets)
        nodeList = rootEl.getElementsByTagNameNS(namespace, APP);
        if (nodeList != null && nodeList.getLength() > 0) {
            for (int i = 0; i < nodeList.getLength(); i++) {
                Element appElement = (Element) nodeList.item(i);
                String id = appElement.getAttribute(ID_ATTRIBUTE);
                if (id != null) {
                    String position = null;
                    String hrefLink = null;
                    String hrefType = null;
                    Node positionNode = appElement.getElementsByTagNameNS(namespace, POSITION).item(0);
                    if (positionNode != null) {
                        Element positionElement = (Element) positionNode;
                        position = positionElement.getTextContent();
                    }
                    Node linkNode = appElement.getElementsByTagNameNS(namespace, LINK).item(0);
                    if (linkNode != null) {
                        Element linkElement = (Element) linkNode;
                        hrefLink = linkElement.getAttribute(HREF);
                        hrefType = linkElement.getAttribute(TYPE_ATTRIBUTE);
                    }
                    omdlInputAdapter.addToAppMap(new OmdlWidgetReference(id, hrefLink, hrefType), position);
                }
            }
        }
        // store the string found in the xml file
        omdlInputAdapter.setLayoutCode(layoutCode);
        // update this string into a RAVE layout
        omdlInputAdapter.setLayoutCode(OmdlModelUtils.getRaveLayoutForImport(omdlInputAdapter));
    }

    private Document initializeBuilder(String rawXml) {
        Document xmlRoot = null;
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
            DocumentBuilder db = dbf.newDocumentBuilder();
            xmlRoot = db.parse(new InputSource(new StringReader(rawXml)));
        } catch (ParserConfigurationException e) {
            logger.error(e.getMessage());
            throw new RuntimeException(e);
        } catch (SAXException e) {
            logger.error(e.getMessage());
            throw new RuntimeException(e);
        } catch (IOException e) {
            logger.error(e.getMessage());
            throw new RuntimeException(e);
        }
        return xmlRoot;
    }

}