All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fabric3.introspection.xml.definitions.DefinitionsLoader Maven / Gradle / Ivy

/*
* Fabric3
* Copyright (c) 2009-2013 Metaform Systems
*
* Fabric3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version, with the
* following exception:
*
* Linking this software statically or dynamically with other
* modules is making a combined work based on this software.
* Thus, the terms and conditions of the GNU General Public
* License cover the whole combination.
*
* As a special exception, the copyright holders of this software
* give you permission to link this software with independent
* modules to produce an executable, regardless of the license
* terms of these independent modules, and to copy and distribute
* the resulting executable under terms of your choice, provided
* that you also meet, for each linked independent module, the
* terms and conditions of the license of that module. An
* independent module is a module which is not derived from or
* based on this software. If you modify this software, you may
* extend this exception to your version of the software, but
* you are not obligated to do so. If you do not wish to do so,
* delete this exception statement from your version.
*
* Fabric3 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 Fabric3.
* If not, see .
*/
package org.fabric3.introspection.xml.definitions;

import javax.xml.namespace.QName;
import javax.xml.stream.Location;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.fabric3.host.contribution.InstallException;
import org.fabric3.model.type.definitions.AbstractPolicyDefinition;
import org.fabric3.model.type.definitions.BindingType;
import org.fabric3.model.type.definitions.ExternalAttachment;
import org.fabric3.model.type.definitions.ImplementationType;
import org.fabric3.model.type.definitions.Intent;
import org.fabric3.model.type.definitions.IntentType;
import org.fabric3.model.type.definitions.PolicySet;
import org.fabric3.model.type.definitions.Qualifier;
import org.fabric3.spi.contribution.Resource;
import org.fabric3.spi.contribution.ResourceElement;
import org.fabric3.spi.contribution.Symbol;
import org.fabric3.spi.contribution.manifest.QNameSymbol;
import org.fabric3.spi.contribution.xml.XmlResourceElementLoader;
import org.fabric3.spi.contribution.xml.XmlResourceElementLoaderRegistry;
import org.fabric3.spi.introspection.IntrospectionContext;
import org.fabric3.spi.introspection.xml.Loader;
import org.fabric3.spi.introspection.xml.UnrecognizedAttribute;
import org.fabric3.spi.introspection.xml.UnrecognizedElement;
import org.oasisopen.sca.annotation.EagerInit;
import org.oasisopen.sca.annotation.Init;
import org.oasisopen.sca.annotation.Reference;
import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
import static org.oasisopen.sca.Constants.SCA_NS;

/**
 * Loader for policy definitions.
 */
@EagerInit
public class DefinitionsLoader implements XmlResourceElementLoader {

    static final QName INTENT = new QName(SCA_NS, "intent");
    static final QName POLICY_SET = new QName(SCA_NS, "policySet");
    static final QName BINDING_TYPE = new QName(SCA_NS, "bindingType");
    static final QName IMPLEMENTATION_TYPE = new QName(SCA_NS, "implementationType");
    static final QName DEFINITIONS = new QName(SCA_NS, "definitions");
    static final QName EXTERNAL_ATTACHMENT = new QName(SCA_NS, "externalAttachment");

    private XmlResourceElementLoaderRegistry elementLoaderRegistry;
    private Loader loaderRegistry;

    public DefinitionsLoader(@Reference XmlResourceElementLoaderRegistry elementLoaderRegistry, @Reference Loader loader) {
        this.elementLoaderRegistry = elementLoaderRegistry;
        this.loaderRegistry = loader;
    }

    @Init
    public void init() {
        elementLoaderRegistry.register(this);
    }

    public QName getType() {
        return DEFINITIONS;
    }

    public void load(XMLStreamReader reader, Resource resource, IntrospectionContext context) throws InstallException, XMLStreamException {

        validateAttributes(reader, context);
        List definitions = new ArrayList();
        String oldNamespace = context.getTargetNamespace();
        String targetNamespace = reader.getAttributeValue(null, "targetNamespace");
        context.setTargetNamespace(targetNamespace);
        while (true) {
            switch (reader.next()) {
                case START_ELEMENT:
                    Location location = reader.getLocation();
                    QName qname = reader.getName();
                    AbstractPolicyDefinition definition = null;
                    if (INTENT.equals(qname)) {
                        definition = loaderRegistry.load(reader, Intent.class, context);
                    } else if (POLICY_SET.equals(qname)) {
                        definition = loaderRegistry.load(reader, PolicySet.class, context);
                    } else if (BINDING_TYPE.equals(qname)) {
                        definition = loaderRegistry.load(reader, BindingType.class, context);
                    } else if (IMPLEMENTATION_TYPE.equals(qname)) {
                        definition = loaderRegistry.load(reader, ImplementationType.class, context);
                    } else if (EXTERNAL_ATTACHMENT.equals(qname)) {
                        definition = loaderRegistry.load(reader, ExternalAttachment.class, context);
                    } else {
                        UnrecognizedElement failure = new UnrecognizedElement(reader, location);
                        context.addError(failure);
                    }
                    if (definition != null) {
                        if (definitions.contains(definition)) {
                            QName name = definition.getName();
                            DuplicatePolicyDefinition error = new DuplicatePolicyDefinition("Duplicate policy definition: " + name, location);
                            context.addError(error);
                        }
                        definitions.add(definition);
                    }
                    break;
                case END_ELEMENT:
                    // update indexed elements with the loaded definitions
                    for (AbstractPolicyDefinition candidate : definitions) {
                        if (candidate instanceof ExternalAttachment) {
                            // External attachments must be added here and not during indexing since they have synthetic names
                            QNameSymbol symbol = new QNameSymbol(candidate.getName());
                            ResourceElement element = new ResourceElement(symbol);
                            element.setValue(candidate);
                            resource.addResourceElement(element);

                            continue;
                        }
                        boolean found = false;
                        for (ResourceElement element : resource.getResourceElements()) {
                            Symbol candidateSymbol = new QNameSymbol(candidate.getName());
                            if (element.getSymbol().equals(candidateSymbol)) {
                                //noinspection unchecked
                                element.setValue(candidate);
                                found = true;
                            }
                        }
                        if (!found) {
                            String id = candidate.toString();
                            throw new AssertionError("Definition not found: " + id);
                        }
                        if (candidate instanceof Intent) {
                            expandQualifiers((Intent) candidate, resource);
                        }
                    }
                    context.setTargetNamespace(oldNamespace);
                    return;
            }
        }

    }

    /**
     * Creates Intent instances from qualifier entries defined in an unqualified (parent) intent.
     *
     * @param intent   the unqualified intent
     * @param resource the contribution resource containing the intents
     */
    private void expandQualifiers(Intent intent, Resource resource) {
        String ns = intent.getName().getNamespaceURI();
        String localPart = intent.getName().getLocalPart();
        for (Qualifier qualifier : intent.getQualifiers()) {
            QName qualifierName = new QName(ns, localPart + "." + qualifier.getName());
            QName constrains = intent.getConstrains();
            Set requires = intent.getRequires();
            IntentType intentType = intent.getIntentType();
            boolean isDefault = qualifier.isDefault();
            Set excludes = new HashSet(intent.getExcludes());
            if (intent.isMutuallyExclusive()) {
                // for each qualified intent, add the others as excludes
                for (Qualifier entry : intent.getQualifiers()) {
                    if (entry == qualifier) {
                        continue;  // skip self
                    }
                    excludes.add(new QName(ns, localPart + "." + entry.getName()));
                }
            }
            Intent qualified = new Intent(qualifierName, constrains, requires, Collections.emptySet(), false, excludes, intentType, isDefault);
            QNameSymbol symbol = new QNameSymbol(qualifierName);
            ResourceElement element = new ResourceElement(symbol);
            element.setValue(qualified);
            resource.addResourceElement(element);
        }
    }

    private void validateAttributes(XMLStreamReader reader, IntrospectionContext context) {
        Location location = reader.getLocation();
        for (int i = 0; i < reader.getAttributeCount(); i++) {
            String name = reader.getAttributeLocalName(i);
            if (!"targetNamespace".equals(name)) {
                UnrecognizedAttribute failure = new UnrecognizedAttribute(name, location);
                context.addError(failure);
            }
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy