/* * 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.tuscany.sca.policy.xml; import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import javax.xml.namespace.QName; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; import org.apache.tuscany.sca.contribution.resolver.ModelResolver; import org.apache.tuscany.sca.contribution.service.ContributionReadException; import org.apache.tuscany.sca.contribution.service.ContributionResolveException; import org.apache.tuscany.sca.contribution.service.ContributionWriteException; import org.apache.tuscany.sca.policy.Intent; import org.apache.tuscany.sca.policy.Policy; import org.apache.tuscany.sca.policy.PolicyFactory; import org.apache.tuscany.sca.policy.PolicySet; /* * Processor for handling xml models of PolicySet definitions */ public class PolicySetProcessor implements StAXArtifactProcessor, PolicyConstants { private PolicyFactory policyFactory; protected StAXArtifactProcessor extensionProcessor; public PolicySetProcessor(PolicyFactory policyFactory, StAXArtifactProcessor extensionProcessor) { this.policyFactory = policyFactory; this.extensionProcessor = extensionProcessor; } public PolicySet read(XMLStreamReader reader) throws ContributionReadException { try { PolicySet policySet = policyFactory.createPolicySet(); policySet.setName(getQName(reader, NAME)); policySet.setAppliesTo(reader.getAttributeValue(null, APPLIES_TO)); readProvidedIntents(policySet, reader); int event = reader.getEventType(); QName name = null; reader.next(); while (reader.hasNext()) { event = reader.getEventType(); switch (event) { case START_ELEMENT : { name = reader.getName(); if ( POLICY_INTENT_MAP_QNAME.equals(name) ) { Intent mappedIntent = policyFactory.createIntent(); mappedIntent.setName(getQName(reader, PROVIDES)); if ( policySet.getProvidedIntents().contains(mappedIntent) ) { readIntentMap(reader, policySet, mappedIntent); } else { throw new ContributionReadException("Intent Map provides for Intent not spcified as provided by parent PolicySet - " +policySet.getName()); } } else if ( POLICY_SET_REFERENCE_QNAME.equals(name) ) { PolicySet referredPolicySet = policyFactory.createPolicySet(); referredPolicySet.setName(getQName(reader, NAME)); policySet.getReferencedPolicySets().add(referredPolicySet); } else { Object extension = extensionProcessor.read(reader); if ( extension instanceof Policy ) { policySet.getPolicies().add(extension); } } break; } } if ( event == END_ELEMENT ) { if ( POLICY_SET_QNAME.equals(reader.getName()) ) { break; } } //Read the next element if (reader.hasNext()) { reader.next(); } } return policySet; } catch (XMLStreamException e) { throw new ContributionReadException(e); } } public void readIntentMap(XMLStreamReader reader, PolicySet policySet, Intent mappedIntent) throws ContributionReadException { QName name = reader.getName(); Map> mappedPolicies = policySet.getMappedPolicies(); if ( POLICY_INTENT_MAP_QNAME.equals(name) ) { //Intent mappedIntent = policyFactory.createIntent(); //mappedIntent.setName(getQName(reader, PROVIDES)); String defaultQualifier = getString(reader, DEFAULT); String qualifierName = null; String qualfiedIntentName = null; Intent qualifiedIntent = null; int event = reader.getEventType(); try { reader.next(); while (reader.hasNext()) { event = reader.getEventType(); switch (event) { case START_ELEMENT : { name = reader.getName(); if ( POLICY_INTENT_MAP_QUALIFIER_QNAME.equals(name)) { qualifierName = getString(reader, NAME); qualfiedIntentName = mappedIntent.getName().getLocalPart() + QUALIFIER + qualifierName; qualifiedIntent = policyFactory.createIntent(); qualifiedIntent.setName(new QName(mappedIntent.getName().getNamespaceURI(), qualfiedIntentName)); } else if ( POLICY_INTENT_MAP_QNAME.equals(name) ) { QName providedIntent = getQName(reader, PROVIDES); if ( qualifierName.equals(providedIntent.getLocalPart()) ) { readIntentMap(reader, policySet, qualifiedIntent); } else { throw new ContributionReadException("Intent provided by IntentMap " + providedIntent + " does not match parent qualifier " + qualifierName + " in policyset - " + policySet); } } else { Object extension = extensionProcessor.read(reader); if ( extension instanceof Policy ) { List policyList = mappedPolicies.get(qualifiedIntent); if ( policyList == null ) { policyList = new ArrayList(); mappedPolicies.put(qualifiedIntent, policyList); if (qualifierName.equals(defaultQualifier)) { mappedPolicies.put(mappedIntent, policyList); } } policyList.add((Policy)extension); } } break; } case END_ELEMENT : { if ( POLICY_INTENT_MAP_QNAME.equals(reader.getName()) ) { if ( defaultQualifier != null ) { String qualifiedIntentName = mappedIntent.getName().getLocalPart() + QUALIFIER + defaultQualifier; Intent defaultQualifiedIntent = policyFactory.createIntent(); defaultQualifiedIntent.setName(new QName(mappedIntent.getName().getNamespaceURI(), qualifiedIntentName)); List policyList = mappedPolicies.get(defaultQualifiedIntent); if ( policyList != null ) { mappedPolicies.put(mappedIntent, policyList); } else { throw new ContributionReadException("Unable to map policies for default qualifier in IntentMap for - " + mappedIntent + " in policy set - " + policySet); } defaultQualifier = null; } } break; } } if ( event == END_ELEMENT && POLICY_INTENT_MAP_QNAME.equals(reader.getName()) ) { break; } //Read the next element if (reader.hasNext()) { reader.next(); } } } catch (XMLStreamException e) { throw new ContributionReadException(e); } } } public void write(PolicySet policySet, XMLStreamWriter writer) throws ContributionWriteException { try { // Write an writer.writeStartElement(SCA10_NS, POLICY_SET); writer.writeNamespace(policySet.getName().getPrefix(), policySet.getName().getNamespaceURI()); writer.writeAttribute(NAME, policySet.getName().getPrefix() + COLON + policySet.getName().getLocalPart()); writer.writeAttribute(APPLIES_TO, policySet.getAppliesTo()); writeProvidedIntents(policySet, writer); writer.writeEndElement(); } catch (XMLStreamException e) { throw new ContributionWriteException(e); } } protected void readProvidedIntents(PolicySet policySet, XMLStreamReader reader) { String value = reader.getAttributeValue(null, PROVIDES); if (value != null) { List providedIntents = policySet.getProvidedIntents(); for (StringTokenizer tokens = new StringTokenizer(value); tokens.hasMoreTokens();) { QName qname = getQNameValue(reader, tokens.nextToken()); Intent intent = policyFactory.createIntent(); intent.setName(qname); providedIntents.add(intent); } } } protected void writeProvidedIntents(PolicySet policySet, XMLStreamWriter writer) throws XMLStreamException { if (policySet.getProvidedIntents() != null && policySet.getProvidedIntents().size() > 0) { StringBuffer sb = new StringBuffer(); for (Intent providedIntents : policySet.getProvidedIntents()) { sb.append(providedIntents.getName()); sb.append(" "); } writer.writeAttribute(PolicyConstants.PROVIDES, sb.toString()); } } //FIXME This method is never used // private void resolveProvidedIntents(PolicySet policySet, ModelResolver resolver) throws ContributionResolveException { // boolean isUnresolved = false; // if (policySet != null && policySet.isUnresolved()) { // //resolve all provided intents // List providedIntents = new ArrayList(); // for (Intent providedIntent : policySet.getProvidedIntents()) { // if ( providedIntent.isUnresolved() ) { // //policyIntent.getRequiredIntents().remove(requiredIntent); // providedIntent = resolver.resolveModel(Intent.class, providedIntent); // providedIntents.add(providedIntent); // if (providedIntent.isUnresolved()) { // isUnresolved = true; // } // } // } // policySet.getProvidedIntents().clear(); // policySet.getProvidedIntents().addAll(providedIntents); // } // policySet.setUnresolved(isUnresolved); // } //FIXME This method is never used // private void resolveIntentsInMappedPolicies(PolicySet policySet, ModelResolver resolver) throws ContributionResolveException { // Map> mappedPolicies = new Hashtable>(); // boolean isUnresolved = false; // for ( Intent mappedIntent : policySet.getMappedPolicies().keySet() ) { // if ( mappedIntent.isUnresolved() ) { // //policyIntent.getRequiredIntents().remove(requiredIntent); // mappedIntent = resolver.resolveModel(Intent.class, mappedIntent); // mappedPolicies.put(mappedIntent, policySet.getMappedPolicies().get(mappedIntent)); // if (mappedIntent.isUnresolved()) { // isUnresolved = true; // } // } // } // // policySet.getMappedPolicies().clear(); // policySet.getMappedPolicies().putAll(mappedPolicies); // policySet.setUnresolved(isUnresolved); // } private void resolvePolicies(PolicySet policySet, ModelResolver resolver) throws ContributionResolveException { boolean unresolved = false; for ( Object o : policySet.getPolicies() ) { extensionProcessor.resolve(o, resolver); if ( o instanceof Policy && ((Policy)o).isUnresolved() ) { unresolved = true; } } policySet.setUnresolved(unresolved); } public void resolve(PolicySet policySet, ModelResolver resolver) throws ContributionResolveException { if ( policySet.isUnresolved() ) { //resolve the policy attachments resolvePolicies(policySet, resolver); if ( !policySet.isUnresolved() ) { resolver.addModel(policySet); } } } public QName getArtifactType() { return POLICY_SET_QNAME; } public Class getModelType() { return PolicySet.class; } protected QName getQNameValue(XMLStreamReader reader, String value) { if (value != null) { int index = value.indexOf(':'); String prefix = index == -1 ? "" : value.substring(0, index); String localName = index == -1 ? value : value.substring(index + 1); String ns = reader.getNamespaceContext().getNamespaceURI(prefix); if (ns == null) { ns = ""; } return new QName(ns, localName, prefix); } else { return null; } } protected QName getQName(XMLStreamReader reader, String name) { String qname = reader.getAttributeValue(null, name); return getQNameValue(reader, qname); } protected String getString(XMLStreamReader reader, String name) { return reader.getAttributeValue(null, name); } }