001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.ws.policy.attachment.external;
019:
020: import java.io.InputStream;
021: import java.util.ArrayList;
022: import java.util.Collection;
023: import java.util.ResourceBundle;
024:
025: import javax.xml.namespace.QName;
026:
027: import org.w3c.dom.Document;
028: import org.w3c.dom.Element;
029: import org.w3c.dom.Node;
030: import org.w3c.dom.NodeList;
031:
032: import org.apache.cxf.Bus;
033: import org.apache.cxf.common.i18n.BundleUtils;
034: import org.apache.cxf.common.i18n.Message;
035: import org.apache.cxf.helpers.DOMUtils;
036: import org.apache.cxf.service.model.BindingFaultInfo;
037: import org.apache.cxf.service.model.BindingMessageInfo;
038: import org.apache.cxf.service.model.BindingOperationInfo;
039: import org.apache.cxf.service.model.EndpointInfo;
040: import org.apache.cxf.service.model.ServiceInfo;
041: import org.apache.cxf.ws.policy.PolicyConstants;
042: import org.apache.cxf.ws.policy.PolicyException;
043: import org.apache.cxf.ws.policy.PolicyProvider;
044: import org.apache.cxf.ws.policy.attachment.AbstractPolicyProvider;
045: import org.apache.cxf.ws.policy.attachment.reference.LocalDocumentReferenceResolver;
046: import org.apache.cxf.ws.policy.attachment.reference.ReferenceResolver;
047: import org.apache.neethi.Policy;
048: import org.apache.neethi.PolicyReference;
049: import org.springframework.core.io.Resource;
050:
051: /**
052: *
053: */
054: public class ExternalAttachmentProvider extends AbstractPolicyProvider
055: implements PolicyProvider {
056:
057: private static final ResourceBundle BUNDLE = BundleUtils
058: .getBundle(ExternalAttachmentProvider.class);
059:
060: // Use a Resource object here instead of a String so that the resource can be resolved when
061: // this bean is created
062:
063: private Resource location;
064: private Collection<PolicyAttachment> attachments;
065:
066: ExternalAttachmentProvider() {
067: }
068:
069: ExternalAttachmentProvider(Bus b) {
070: super (b);
071: }
072:
073: public void setLocation(Resource u) {
074: location = u;
075: }
076:
077: public Resource getLocation() {
078: return location;
079: }
080:
081: public Policy getEffectivePolicy(BindingFaultInfo bfi) {
082: readDocument();
083: Policy p = new Policy();
084: for (PolicyAttachment pa : attachments) {
085: if (pa.appliesTo(bfi)) {
086: p = p.merge(pa.getPolicy());
087: }
088: }
089:
090: return p;
091: }
092:
093: public Policy getEffectivePolicy(BindingMessageInfo bmi) {
094: readDocument();
095: Policy p = new Policy();
096: for (PolicyAttachment pa : attachments) {
097: if (pa.appliesTo(bmi)) {
098: p = p.merge(pa.getPolicy());
099: }
100: }
101:
102: return p;
103: }
104:
105: public Policy getEffectivePolicy(BindingOperationInfo boi) {
106: readDocument();
107: Policy p = new Policy();
108: for (PolicyAttachment pa : attachments) {
109: if (pa.appliesTo(boi)) {
110: p = p.merge(pa.getPolicy());
111: }
112: }
113:
114: return p;
115: }
116:
117: public Policy getEffectivePolicy(EndpointInfo ei) {
118: readDocument();
119: Policy p = new Policy();
120: for (PolicyAttachment pa : attachments) {
121: if (pa.appliesTo(ei)) {
122: p = p.merge(pa.getPolicy());
123: }
124: }
125:
126: return p;
127: }
128:
129: public Policy getEffectivePolicy(ServiceInfo si) {
130: readDocument();
131: Policy p = new Policy();
132: for (PolicyAttachment pa : attachments) {
133: if (pa.appliesTo(si)) {
134: p = p.merge(pa.getPolicy());
135: }
136: }
137:
138: return p;
139: }
140:
141: void readDocument() {
142: if (null != attachments) {
143: return;
144: }
145:
146: // read the document and build the attachments
147: attachments = new ArrayList<PolicyAttachment>();
148: Document doc = null;
149: try {
150: InputStream is = location.getInputStream();
151: if (null == is) {
152: throw new PolicyException(new Message(
153: "COULD_NOT_OPEN_ATTACHMENT_DOC_EXC", BUNDLE,
154: location));
155: }
156: doc = DOMUtils.readXml(is);
157: } catch (Exception ex) {
158: throw new PolicyException(ex);
159: }
160:
161: PolicyConstants constants = null;
162: if (null != bus) {
163: constants = bus.getExtension(PolicyConstants.class);
164: }
165: if (null == constants) {
166: constants = new PolicyConstants();
167: }
168: NodeList nl = doc.getElementsByTagNameNS(constants
169: .getNamespace(), constants
170: .getPolicyAttachmentElemName());
171: for (int i = 0; i < nl.getLength(); i++) {
172:
173: PolicyAttachment attachment = new PolicyAttachment();
174:
175: Element ae = (Element) nl.item(i);
176:
177: for (Node nd = ae.getFirstChild(); nd != null; nd = nd
178: .getNextSibling()) {
179: if (Node.ELEMENT_NODE != nd.getNodeType()) {
180: continue;
181: }
182: QName qn = new QName(nd.getNamespaceURI(), nd
183: .getLocalName());
184: if (constants.getAppliesToElemQName().equals(qn)) {
185: Collection<DomainExpression> des = readDomainExpressions((Element) nd);
186: if (des.isEmpty()) {
187: // forget about this attachment
188: continue;
189: }
190: attachment.setDomainExpressions(des);
191: } else if (constants.getPolicyElemQName().equals(qn)) {
192: Policy p = builder.getPolicy((Element) nd);
193: if (null != attachment.getPolicy()) {
194: p = p.merge(attachment.getPolicy());
195: }
196: attachment.setPolicy(p);
197: } else if (constants.getPolicyReferenceElemQName()
198: .equals(qn)) {
199: PolicyReference ref = builder
200: .getPolicyReference((Element) nd);
201: if (null != ref) {
202: Policy p = resolveReference(ref, doc);
203: if (null != attachment.getPolicy()) {
204: p = p.merge(attachment.getPolicy());
205: }
206: attachment.setPolicy(p);
207: }
208: } // TODO: wsse:Security child element
209: }
210:
211: if (null == attachment.getPolicy()
212: || null == attachment.getDomainExpressions()) {
213: continue;
214: }
215:
216: attachments.add(attachment);
217: }
218: }
219:
220: Policy resolveReference(PolicyReference ref, Document doc) {
221: Policy p = null;
222: if (isExternal(ref)) {
223: p = resolveExternal(ref, doc.getBaseURI());
224: } else {
225: p = resolveLocal(ref, doc);
226: }
227: checkResolved(ref, p);
228: return p;
229: }
230:
231: Policy resolveLocal(PolicyReference ref, Document doc) {
232: String relativeURI = ref.getURI().substring(1);
233: String absoluteURI = doc.getBaseURI() + ref.getURI();
234: Policy resolved = registry.lookup(absoluteURI);
235: if (null != resolved) {
236: return resolved;
237: }
238: ReferenceResolver resolver = new LocalDocumentReferenceResolver(
239: doc, builder, bus.getExtension(PolicyConstants.class));
240: resolved = resolver.resolveReference(relativeURI);
241: if (null != resolved) {
242: ref.setURI(absoluteURI);
243: registry.register(absoluteURI, resolved);
244: }
245: return resolved;
246: }
247:
248: Collection<DomainExpression> readDomainExpressions(
249: Element appliesToElem) {
250: Collection<DomainExpression> des = new ArrayList<DomainExpression>();
251: for (Node nd = appliesToElem.getFirstChild(); nd != null; nd = nd
252: .getNextSibling()) {
253: if (Node.ELEMENT_NODE == nd.getNodeType()) {
254: DomainExpressionBuilderRegistry debr = bus
255: .getExtension(DomainExpressionBuilderRegistry.class);
256: assert null != debr;
257: DomainExpression de = debr.build((Element) nd);
258: des.add(de);
259: }
260: }
261: return des;
262: }
263:
264: // for test
265:
266: void setAttachments(Collection<PolicyAttachment> a) {
267: attachments = a;
268: }
269:
270: Collection<PolicyAttachment> getAttachments() {
271: return attachments;
272: }
273:
274: }
|