io.smartspaces.workbench.project.jdom.JdomProjectGroupTemplateSpecificationReader.java Source code

Java tutorial

Introduction

Here is the source code for io.smartspaces.workbench.project.jdom.JdomProjectGroupTemplateSpecificationReader.java

Source

/*
 * Copyright (C) 2016 Keith M. Hughes
 * Copyright (C) 2014 Google Inc.
 *
 * 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 io.smartspaces.workbench.project.jdom;

import io.smartspaces.SimpleSmartSpacesException;
import io.smartspaces.resource.Version;
import io.smartspaces.workbench.SmartSpacesWorkbench;
import io.smartspaces.workbench.project.Project;
import io.smartspaces.workbench.project.ProjectGroupTemplateSpecificationReader;
import io.smartspaces.workbench.project.creator.TemplateAssignConstituent;
import io.smartspaces.workbench.project.creator.TemplateFileConstituent;
import io.smartspaces.workbench.project.group.GroupProjectTemplateSpecification;

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

import org.jdom2.Attribute;
import org.jdom2.Element;
import org.jdom2.Namespace;

/**
 * Reader for a XML-based project group using jdom.
 *
 * @author Trevor Pering
 */
public class JdomProjectGroupTemplateSpecificationReader extends JdomReader
        implements ProjectGroupTemplateSpecificationReader {

    /**
     * Element name for a project group.
     */
    public static final String PROJECT_GROUP_TEMPLATE_SPECIFICATION_ELEMENT_NAME = "projectGroupTemplateSpecification";

    /**
     * Element name for a project group.
     */
    public static final String PROJECT_GROUP_ELEMENT_NAME = "projectGroup";

    /**
     * Add all the base constituent types to the static map.
     */
    {
        addConstituentType(new TemplateFileConstituent.TemplateFileConstituentFactory());
        addConstituentType(new TemplateAssignConstituent.TemplateAssignConstituentFactory());
    }

    /**
     * Construct a project reader.
     *
     * @param workbench
     *          the workbench to use
     */
    public JdomProjectGroupTemplateSpecificationReader(SmartSpacesWorkbench workbench) {
        super(workbench);
        setJdomPrototypeProcessor(new JdomPrototypeProcessor());
    }

    @Override
    public GroupProjectTemplateSpecification readProjectGroupTemplateSpecification(File specFile) {
        try {
            Element rootElement = getRootElement(specFile);
            String type = rootElement.getName();
            GroupProjectTemplateSpecification specification;
            if (PROJECT_GROUP_TEMPLATE_SPECIFICATION_ELEMENT_NAME.equals(type)) {
                specification = makeFromElement(rootElement);
            } else if (PROJECT_GROUP_ELEMENT_NAME.equals(type)) {
                specification = makeFromElement(rootElement);
            } else {
                throw new SimpleSmartSpacesException("Unknown root element type " + type);
            }
            specification.setSpecificationSource(specFile);
            return specification;
        } catch (Exception e) {
            throw new SimpleSmartSpacesException(
                    "While processing specification file " + specFile.getAbsolutePath(), e);
        }
    }

    /**
     * Create a project group from a given element.
     *
     * @param rootElement
     *          input element
     *
     * @return new specification
     */
    private GroupProjectTemplateSpecification makeFromElement(Element rootElement) {
        Namespace namespace = rootElement.getNamespace();

        GroupProjectTemplateSpecification groupProjectTemplateSpecification = new GroupProjectTemplateSpecification();

        List<Element> children = getChildren(rootElement);
        for (Element child : children) {
            addElementToSpec(groupProjectTemplateSpecification, namespace, child);
        }

        return groupProjectTemplateSpecification;
    }

    /**
     * Add the given element to the spec.
     *
     * @param spec
     *          specification to configure
     * @param namespace
     *          XML namespace for elements
     * @param child
     *          child element to add
     */
    private void addElementToSpec(GroupProjectTemplateSpecification spec, Namespace namespace, Element child) {
        String name = child.getName();

        try {
            if (JdomProjectReader.PROJECT_GROUP_ELEMENT_NAME.equals(name)) {
                addProjects(spec, child);
            } else if (JdomPrototypeProcessor.GROUP_ELEMENT_NAME.equals(name)) {
                addPrototypes(spec, child);
            } else if (JdomProjectReader.PROJECT_ELEMENT_NAME_NAME.equals(name)) {
                spec.setName(child.getTextTrim());
            } else if (JdomProjectReader.PROJECT_ELEMENT_NAME_DESCRIPTION.equals(name)) {
                spec.setDescription(child.getTextTrim());
            } else if (JdomReader.PROJECT_ELEMENT_NAME_TEMPLATES.equals(name)) {
                // This is really a prototype chain for the entire group project, but we
                // need to control when it is processed,
                // so instead snarf the attribute from the templates element when it is
                // processed.
                processPrototypeChain(spec, namespace, child);
                spec.addExtraConstituents(getContainerConstituents(namespace, child, null));
            } else if (JdomProjectReader.PROJECT_ELEMENT_NAME_VERSION.equals(name)) {
                spec.setVersion(Version.parseVersion(child.getTextTrim()));
            } else {
                throw new SimpleSmartSpacesException("Unrecognized element name: " + name);
            }
        } catch (Exception e) {
            throw new SimpleSmartSpacesException("While processing projectGroup element: " + name, e);
        }
    }

    /**
     * Add all prototypes to the specification.
     *
     * @param spec
     *          specification to configure
     * @param group
     *          prototype group to add
     */
    private void addPrototypes(GroupProjectTemplateSpecification spec, Element group) {
        List<Element> children = getChildren(group);
        for (Element entry : children) {
            getJdomPrototypeProcessor().addPrototypeElement(entry);
        }
    }

    /**
     * Process the prototype chain for the given element.
     *
     * @param spec
     *          specification to configure
     * @param namespace
     *          XML namespace for elements
     * @param projectElement
     *          element to populate from
     */
    private void processPrototypeChain(GroupProjectTemplateSpecification spec, Namespace namespace,
            Element projectElement) {
        if (getJdomPrototypeProcessor() != null) {
            List<Element> prototypeChain = getJdomPrototypeProcessor().getPrototypeChain(projectElement);
            for (Element prototype : prototypeChain) {
                configureProjectGroupFromElement(spec, namespace, prototype);
            }
            // Remove the not-useful prototype's name, since it would incorrectly be
            // naming this element.
            spec.getAttributes().remove(JdomPrototypeProcessor.PROTOTYPE_NAME_ATTRIBUTE);
        }
    }

    /**
     * Configure a project given an element.
     *
     * @param spec
     *          specification to configure
     * @param namespace
     *          XML namespace for elements
     * @param projectElement
     *          project element to read from
     */
    private void configureProjectGroupFromElement(GroupProjectTemplateSpecification spec, Namespace namespace,
            Element projectElement) {
        getSpecificationAttributes(spec, projectElement);
        getMainData(spec, namespace, projectElement);

        spec.addExtraConstituents(getContainerConstituents(namespace,
                projectElement.getChild(JdomReader.PROJECT_ELEMENT_NAME_TEMPLATES), null));
    }

    /**
     * Get any attributes attached to the project.
     *
     * @param spec
     *          the specification whose data is being read
     * @param rootElement
     *          root element of the XML DOM containing the project data
     */
    private void getSpecificationAttributes(GroupProjectTemplateSpecification spec, Element rootElement) {
        @SuppressWarnings("unchecked")
        List<Attribute> attributes = rootElement.getAttributes();
        for (Attribute attribute : attributes) {
            spec.addAttribute(attribute.getName(), attribute.getValue());
        }
    }

    /**
     * Add all projects to the spec.
     *
     * @param spec
     *          spec to add
     * @param group
     *          projects group to add
     */
    private void addProjects(GroupProjectTemplateSpecification spec, Element group) {
        List<Element> children = getChildren(group);
        for (Element entry : children) {
            JdomProjectReader projectReader = new JdomProjectReader(getWorkbench());
            projectReader.addConstituentType(new TemplateFileConstituent.TemplateFileConstituentFactory());
            projectReader.addConstituentType(new TemplateAssignConstituent.TemplateAssignConstituentFactory());
            projectReader.setJdomPrototypeProcessor(getJdomPrototypeProcessor());
            Project project = projectReader.makeProjectFromElement(entry);
            project.setSpecificationSource(spec.getSpecificationSource());
            project.setBaseDirectory(new File("."));
            spec.addProject(project);
        }
    }

    /**
     * Get the main data from the document.
     *
     * @param spec
     *          the specification whose data is being read
     * @param namespace
     *          XML namespace for elements
     * @param rootElement
     *          root element to read from
     */
    private void getMainData(GroupProjectTemplateSpecification spec, Namespace namespace, Element rootElement) {
        spec.setName(getChildTextTrimmed(rootElement, namespace, JdomProjectReader.PROJECT_ELEMENT_NAME_NAME,
                spec.getName()));
        spec.setDescription(getChildTextTrimmed(rootElement, namespace,
                JdomProjectReader.PROJECT_ELEMENT_NAME_DESCRIPTION, spec.getDescription()));

        String version = getChildTextTrimmed(rootElement, namespace,
                JdomProjectReader.PROJECT_ELEMENT_NAME_VERSION);
        if (version != null) {
            spec.setVersion(Version.parseVersion(version));
        }
    }
}