blob: 1da0034994f23f63439fbab6b06cbfd9c2c5b31a [file] [log] [blame]
/**
* 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.neethi;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import org.apache.neethi.util.PolicyIntersector;
/**
* Policy is a PolicyOperator that requires to satisfy all of its
* PolicyComponents. It is always the outermost component of a Policy.
*
*/
public class Policy extends All {
private Map<QName, String> attributes = new HashMap<QName, String>();
private String namespace;
private PolicyRegistry registry;
public Policy() {
}
public Policy(PolicyRegistry r) {
registry = r;
}
public Policy(PolicyRegistry r, String ns) {
this(r);
namespace = ns;
}
public Policy(PolicyOperator parent) {
super(parent);
}
public PolicyRegistry getPolicyRegistry() {
return registry;
}
public void setPolicyRegistry(PolicyRegistry reg) {
registry = reg;
}
public String getNamespace() {
return namespace;
}
/**
* Returns a Normalized version of self. If {@code deep} is set
* {@code false} then the assertions are not normalized and it returns a
* partially normalized version of self.
*
* @param deep
* a flag to indicate whether to normalize the assertions
* @return a Policy that is normalized version of self
*/
public Policy normalize(boolean deep) {
return normalize(registry, deep);
}
/**
* Returns a normalized version of self.If {@code deep} is set
* {@code false} then the assertions are not normalized and it returns a
* partially normalized version of self.
*
* @param reg
* a PolicyRegistry from which the PolicyReferences are resolved
* @param deep
* a flag to indicate whether to normalize the assertions
* @return a normalized version of self
*/
public Policy normalize(PolicyRegistry reg, boolean deep) {
return normalize(this, reg, deep);
}
/**
* Returns a Policy that is the merge of specified Policy and self.
*
* @param policy
* the Policy to be merged with self
* @return a Policy that is the merge of the specified Policy and self
*/
public Policy merge(Policy policy) {
Policy result = new Policy(registry, namespace);
result.addPolicyComponents(getPolicyComponents());
result.addPolicyComponents(policy.getPolicyComponents());
return result;
}
public Policy intersect(Policy policy) {
return intersect(policy, true);
}
public Policy intersect(Policy policy, boolean strict) {
return new PolicyIntersector(strict).intersect(normalize(true), policy.normalize(true), true);
}
/**
* Serializes the Policy to a XMLStreamWriter.
*/
public void serialize(XMLStreamWriter writer) throws XMLStreamException {
String nspace = namespace;
if (namespace == null) {
nspace = Constants.findPolicyNamespace(writer);
}
String wspPrefix = writer.getPrefix(nspace);
if (wspPrefix == null) {
wspPrefix = Constants.ATTR_WSP;
writer.setPrefix(wspPrefix, nspace);
}
String wsuPrefix = writer.getPrefix(Constants.URI_WSU_NS);
if (wsuPrefix == null) {
wsuPrefix = Constants.ATTR_WSU;
writer.setPrefix(wsuPrefix, Constants.URI_WSU_NS);
}
writer.writeStartElement(wspPrefix, Constants.ELEM_POLICY,
nspace);
QName key;
String prefix = null;
String namespaceURI = null;
String localName = null;
Map<String, String> prefix2ns = new HashMap<String, String>();
boolean writeNS = true;
for (Map.Entry<QName, String> ents : attributes.entrySet()) {
key = ents.getKey();
localName = key.getLocalPart();
namespaceURI = key.getNamespaceURI();
namespaceURI = (namespaceURI == null || namespaceURI.length() == 0) ? null : namespaceURI;
if (namespaceURI != null && XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(namespaceURI)) {
writer.writeNamespace(localName, ents.getValue());
if (nspace.equals(ents.getValue())) {
writeNS = false;
}
} else if (namespaceURI != null) {
String writerPrefix = writer.getPrefix(namespaceURI);
writerPrefix = (writerPrefix == null || writerPrefix.length() == 0) ? null : writerPrefix;
if (writerPrefix == null) {
prefix = key.getPrefix();
prefix = (prefix == null || prefix.length() == 0) ? null : prefix;
} else {
prefix = writerPrefix;
}
if (prefix != null) {
writer.writeAttribute(prefix, namespaceURI, localName, ents.getValue());
prefix2ns.put(prefix, key.getNamespaceURI());
} else {
writer.writeAttribute(namespaceURI, localName, ents.getValue());
}
} else {
writer.writeAttribute(localName, getAttribute(key));
}
}
if (writeNS) {
// writes xmlns:wsp=".."
writer.writeNamespace(wspPrefix, nspace);
}
for (String pfx :prefix2ns.keySet()) {
writer.writeNamespace(pfx, prefix2ns.get(pfx));
}
for (PolicyComponent policyComponent : getPolicyComponents()) {
policyComponent.serialize(writer);
}
writer.writeEndElement();
}
/**
* Returns Constants.TYPE_POLICY
*/
public short getType() {
return Constants.TYPE_POLICY;
}
/**
* Returns an Iterator that will return a list of assertions correspond to a
* Policy alternative if any. The {@code iterator.next()} will return a
* list of assertions correspond to a Policy alternative if any and
* {@code iterator.hasNext()} will indicates whether there is another
* Policy alternative.
*
* @return An iterator over the list of alternatives
*/
public Iterator<List<Assertion>> getAlternatives() {
return new PolicyIterator(this, registry);
}
public Iterator<List<Assertion>> getAlternatives(PolicyRegistry reg) {
return new PolicyIterator(this, reg);
}
private class PolicyIterator implements Iterator<List<Assertion>> {
Iterator<PolicyComponent> alternatives;
public PolicyIterator(Policy policy, PolicyRegistry reg) {
policy = policy.normalize(reg, false);
ExactlyOne exactlyOne = (ExactlyOne) policy
.getFirstPolicyComponent();
alternatives = exactlyOne.getPolicyComponents().iterator();
}
public boolean hasNext() {
return alternatives.hasNext();
}
public List<Assertion> next() {
List<PolicyComponent> pcs = ((All) alternatives.next()).getPolicyComponents();
List<Assertion> asserts = new ArrayList<Assertion>(pcs.size());
for (PolicyComponent pc : pcs) {
if (pc instanceof Assertion) {
asserts.add((Assertion)pc);
}
}
return asserts;
}
public void remove() {
throw new UnsupportedOperationException(
"policyAlternative.remove() is not supported");
}
}
/**
* Adds an attribute to self.
*
* @param name
* the name of the attribute
* @param value
* the value of the attribute
*/
public void addAttribute(QName name, String value) {
attributes.put(name, value);
}
/**
* Returns the value of the attribute specified by the QName. Returns
* {@code null} if not present.
*
* @param name
* the QName of the attribute
* @return the value of the attribute specified by the QName
*/
public String getAttribute(QName name) {
return attributes.get(name);
}
/**
* Returns a {@link Map} of all attributes of self.
*
* @return a Map of all attributes of self
*/
public Map<QName, String> getAttributes() {
return attributes;
}
/**
* Sets the {@code Name} attribute of self.
*
* @param name
* the Name attribute of self
*/
public void setName(String name) {
addAttribute(new QName("", Constants.ATTR_NAME), name);
}
/**
* Returns the {@code Name} attribute of self.
*
* @return the Name attribute of self
*/
public String getName() {
return getAttribute(new QName("", Constants.ATTR_NAME));
}
/**
* Sets the wsu:Id attribute of self.
*
* @param id
* the Id attribute of self
*/
public void setId(String id) {
addAttribute(new QName(Constants.URI_WSU_NS, Constants.ATTR_ID), id);
}
/**
* Returns the Id attribute of self.
*
* @return the Id attribute of self
*/
public String getId() {
return getAttribute(new QName(Constants.URI_WSU_NS, Constants.ATTR_ID));
}
}