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: */
019:
020: package org.apache.axis2.mex;
021:
022: import java.util.ArrayList;
023: import java.util.List;
024: import org.apache.axiom.om.OMElement;
025: import org.apache.axiom.soap.SOAPBody;
026: import org.apache.axiom.soap.SOAPEnvelope;
027: import org.apache.axiom.soap.SOAPFactory;
028: import org.apache.axis2.AxisFault;
029: import org.apache.axis2.context.MessageContext;
030: import org.apache.axis2.dataretrieval.Data;
031: import org.apache.axis2.dataretrieval.DataRetrievalException;
032: import org.apache.axis2.dataretrieval.DataRetrievalRequest;
033: import org.apache.axis2.dataretrieval.OutputForm;
034: import org.apache.axis2.description.AxisService;
035: import org.apache.axis2.description.Parameter;
036: import org.apache.axis2.mex.om.Location;
037: import org.apache.axis2.mex.om.Metadata;
038: import org.apache.axis2.mex.om.MetadataReference;
039: import org.apache.axis2.mex.om.MetadataSection;
040: import org.apache.axis2.mex.om.MexOMException;
041: import org.apache.axis2.mex.util.MexUtil;
042: import org.apache.axis2.receivers.AbstractInOutMessageReceiver;
043: import org.apache.commons.logging.Log;
044: import org.apache.commons.logging.LogFactory;
045:
046: import javax.xml.namespace.QName;
047:
048: /**
049: * Message Receiver for processing WS-MEX GetMetadata request.
050: *
051: */
052: public class MexMessageReceiver extends AbstractInOutMessageReceiver {
053: private static final Log log = LogFactory
054: .getLog(MexMessageReceiver.class);
055: Parameter axisConfigMEXParm = null;
056: Parameter serviceConfigMEXParm = null;
057: String mexNamespaceValue = null;
058:
059: /**
060: * Process GetMetadata request
061: */
062: public void invokeBusinessLogic(MessageContext msgContext,
063: MessageContext newmsgContext) throws AxisFault {
064: AxisService theService = msgContext.getAxisService();
065: axisConfigMEXParm = msgContext.getConfigurationContext()
066: .getAxisConfiguration().getParameter(
067: MexConstants.MEX_CONFIG.MEX_PARM);
068: serviceConfigMEXParm = theService
069: .getParameter(MexConstants.MEX_CONFIG.MEX_PARM);
070:
071: check_MEX_disabled(serviceConfigMEXParm);
072:
073: try {
074: Metadata metadata = handleRequest(msgContext);
075: theService.setEndpointURL(msgContext.getTo().getAddress());
076:
077: if (metadata != null) {
078: SOAPEnvelope envelope = newmsgContext.getEnvelope();
079: if (envelope == null) {
080: SOAPFactory fac = getSOAPFactory(msgContext);
081: envelope = fac.getDefaultEnvelope();
082: }
083:
084: OMElement result = metadata.toOM();
085: if (result != null) {
086: AxisService service = msgContext.getAxisService();
087: result.declareNamespace(service
088: .getTargetNamespace(), service
089: .getTargetNamespacePrefix());
090: envelope.getBody().addChild(result);
091: }
092:
093: newmsgContext.setEnvelope(envelope);
094: }
095: // AxisService service = msgContext.getAxisService();
096:
097: } catch (Exception e) {
098: log.info(e);
099: if (e instanceof MexException) {
100: throw (MexException) e;
101: }
102: throw new MexException(e);
103: }
104:
105: }
106:
107: /*
108: * Handle GetMetadata Request
109: * Interprete GetMetadata request and process request.
110: * @returns Metadata object
111: */
112: private Metadata handleRequest(MessageContext msgContext)
113: throws AxisFault {
114: Metadata metadata = null;
115: SOAPEnvelope envelope = msgContext.getEnvelope();
116:
117: SOAPBody body = envelope.getBody();
118: OMElement aReq = body.getFirstChildWithName(new QName(
119: MexConstants.Spec_2004_09.NS_URI,
120: MexConstants.SPEC.GET_METADATA));
121:
122: List metadata_request_list;
123: if (aReq != null) {
124: mexNamespaceValue = MexConstants.Spec_2004_09.NS_URI;
125: metadata_request_list = determineMetadataTypes(aReq);
126:
127: } else {
128: throw new MexException("Invalid Metadata request");
129: }
130:
131: metadata = processRequest(metadata_request_list, msgContext,
132: aReq);
133:
134: return metadata;
135: }
136:
137: /*
138: * Process the requests
139: *
140: * @param metadata_request_list list of mex Dialect for requesting data
141: * @msgContext MessageContext
142: * @aReq GetMetadata request
143: */
144:
145: public Metadata processRequest(List metadata_request_list,
146: MessageContext msgContext, OMElement aReq)
147: throws MexException {
148:
149: // Instantiate Metadata instance to build the WS-Mex Metadata element
150: SOAPEnvelope envelope = msgContext.getEnvelope();
151: String soapNamespaceURI = envelope.getNamespace()
152: .getNamespaceURI();
153: SOAPFactory factory = MexUtil.getSOAPFactory(soapNamespaceURI);
154:
155: Metadata metadata = new Metadata(factory, mexNamespaceValue);
156: DataRetrievalRequest requestOptions = new DataRetrievalRequest();
157:
158: String identifier_value = null;
159: // Check if Identifier element included in request
160: OMElement dialectElem = aReq.getFirstChildWithName(new QName(
161: mexNamespaceValue, MexConstants.SPEC.DIALECT));
162:
163: if (dialectElem != null) {
164: OMElement identifier = dialectElem
165: .getFirstChildWithName(new QName(mexNamespaceValue,
166: MexConstants.SPEC.IDENTIFIER));
167:
168: if (identifier != null) {
169: identifier_value = identifier.getText();
170: if (identifier_value != null
171: && identifier_value.length() > 0) {
172: requestOptions.putIdentifier(identifier_value);
173: }
174: }
175: }
176:
177: // Process the request and append MetadataSection to Metadata
178: // Loop through the metadata_request_list for Dialect(s)), and setup requestOptions.
179: // Basically, one requestOptions is setup for each supported outputForm for the Dialect
180: // and Identifier specified in the GetMetadata request.
181: int len = metadata_request_list.size();
182: OutputForm[] outputforms;
183:
184: for (int i = 0; i < len; i++) { // metadata request
185:
186: String dialect = "";
187: try {
188: dialect = (String) metadata_request_list.get(i);
189:
190: requestOptions.putDialect(dialect);
191:
192: outputforms = MexUtil.determineOutputForm(dialect,
193: axisConfigMEXParm, serviceConfigMEXParm);
194: // Loop to call AxisService::getData API to retrieve data
195: // for the Dialect and Identifier(if specified) in the request
196: // for each
197: // supported output form.
198:
199: for (int j = 0; j < outputforms.length; j++) { // output form
200: requestOptions.putOutputForm(outputforms[j]);
201:
202: Data[] result = msgContext.getAxisService()
203: .getData(requestOptions, msgContext);
204:
205: ArrayList sections = processData(result,
206: outputforms[j], dialect, identifier_value,
207: factory);
208: metadata.addMetadatSections(sections);
209: }
210:
211: } catch (DataRetrievalException e) {
212: log.error(
213: "Data Retrieval exception detected for dialect, "
214: + dialect, e);
215:
216: throw new MexException(e);
217: } catch (Throwable e) {
218:
219: log.error("Throwable detected for dialect, " + dialect,
220: e);
221: e.printStackTrace();
222:
223: throw new MexException(e);
224: }
225:
226: }
227: return metadata;
228: }
229:
230: /*
231: * Create MetadataSection for each Data element, and add the
232: * MetadataSections to Metadata.
233: */
234: private ArrayList processData(Data[] data, OutputForm outputForm,
235: String dialect, String identifier_value, SOAPFactory factory)
236: throws MexException {
237: MetadataSection section = null;
238: ArrayList sections = new ArrayList();
239: if (data == null || data.length == 0) {
240: if (log.isDebugEnabled())
241: log
242: .debug("No result was returned from getData request for dialect,"
243: + dialect
244: + " Form: "
245: + outputForm.getType()
246: + ". No MetadataSection will be added!");
247:
248: } else {
249: for (int k = 0; k < data.length; k++) {
250:
251: section = createMetadataSection(outputForm, data[k]
252: .getData(), factory, mexNamespaceValue);
253:
254: section.setDialect(dialect);
255: identifier_value = data[k].getIdentifier();
256:
257: if (identifier_value != null) {
258: section.setIdentifier(identifier_value);
259: }
260: sections.add(section);
261:
262: }
263: }
264: return sections;
265: }
266:
267: private MetadataSection createMetadataSection(
268: OutputForm outputForm, Object result, SOAPFactory factory,
269: String mexNamespaceValue) throws MexOMException {
270: MetadataSection section = new MetadataSection(factory,
271: mexNamespaceValue);
272:
273: if (outputForm == OutputForm.INLINE_FORM)
274: section.setinlineData(result);
275: else if (outputForm == OutputForm.LOCATION_FORM)
276: section.setLocation(new Location(factory,
277: mexNamespaceValue, (String) result));
278: else if (outputForm == OutputForm.REFERENCE_FORM) {
279: MetadataReference ref = new MetadataReference(factory,
280: mexNamespaceValue);
281:
282: ref.setEPR((OMElement) result);
283: section.setMetadataReference(ref);
284: } else {
285:
286: section.setinlineData((OMElement) result);
287: }
288:
289: return section;
290: }
291:
292: /*
293: * Traverse and interprete the GetMetadata OMElement for Dialect element
294: * that specified in the request. @returns a List with Dialect(s) of
295: * metadata requested.
296: *
297: */
298: private List determineMetadataTypes(OMElement aReq) {
299: List metadata_request_list = new ArrayList();
300:
301: boolean allTypes = false;
302:
303: OMElement dialect = aReq.getFirstChildWithName(new QName(
304: mexNamespaceValue, MexConstants.SPEC.DIALECT));
305: if (dialect != null) {
306: String dialectText = dialect.getText();
307: if (dialectText != null && dialectText.length() > 0) {
308: metadata_request_list.add(dialectText.trim());
309: } else {
310: allTypes = true;
311: }
312: } else {
313: allTypes = true;
314: }
315:
316: if (allTypes) { // retrieve all metadata
317: metadata_request_list
318: .add(MexConstants.SPEC.DIALECT_TYPE_POLICY);
319: metadata_request_list
320: .add(MexConstants.SPEC.DIALECT_TYPE_SCHEMA);
321: metadata_request_list
322: .add(MexConstants.SPEC.DIALECT_TYPE_WSDL);
323: }
324: return metadata_request_list;
325: }
326:
327: private void check_MEX_disabled(Parameter mexConfig)
328: throws MexDisabledException {
329: if (MexUtil.isMexDisabled(mexConfig)) {
330: throw new MexDisabledException(
331: "'metadataexchange' parameter configured to disable MEX for the service.");
332: }
333: }
334: }
|