| /* |
| * 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.axis2.mex; |
| |
| import org.apache.axiom.om.OMElement; |
| import org.apache.axiom.soap.SOAPBody; |
| import org.apache.axiom.soap.SOAPEnvelope; |
| import org.apache.axiom.soap.SOAPFactory; |
| import org.apache.axis2.AxisFault; |
| import org.apache.axis2.context.MessageContext; |
| import org.apache.axis2.dataretrieval.Data; |
| import org.apache.axis2.dataretrieval.DataRetrievalException; |
| import org.apache.axis2.dataretrieval.DataRetrievalRequest; |
| import org.apache.axis2.dataretrieval.OutputForm; |
| import org.apache.axis2.description.AxisService; |
| import org.apache.axis2.description.Parameter; |
| import org.apache.axis2.mex.om.Location; |
| import org.apache.axis2.mex.om.Metadata; |
| import org.apache.axis2.mex.om.MetadataReference; |
| import org.apache.axis2.mex.om.MetadataSection; |
| import org.apache.axis2.mex.om.MexOMException; |
| import org.apache.axis2.mex.util.MexUtil; |
| import org.apache.axis2.receivers.AbstractInOutMessageReceiver; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| |
| import javax.xml.namespace.QName; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| /** |
| * Message Receiver for processing WS-MEX GetMetadata request. |
| * |
| */ |
| public class MexMessageReceiver extends AbstractInOutMessageReceiver { |
| private static final Log log = LogFactory.getLog(MexMessageReceiver.class); |
| Parameter axisConfigMEXParm = null; |
| Parameter serviceConfigMEXParm = null; |
| String mexNamespaceValue = null; |
| |
| /** |
| * Process GetMetadata request |
| */ |
| public void invokeBusinessLogic(MessageContext msgContext, |
| MessageContext newmsgContext) throws AxisFault { |
| AxisService theService = msgContext.getAxisService(); |
| axisConfigMEXParm = msgContext.getConfigurationContext().getAxisConfiguration().getParameter(MexConstants.MEX_CONFIG.MEX_PARM); |
| serviceConfigMEXParm = theService.getParameter(MexConstants.MEX_CONFIG.MEX_PARM); |
| |
| check_MEX_disabled(serviceConfigMEXParm); |
| |
| try { |
| Metadata metadata = handleRequest(msgContext); |
| theService.setEndpointURL(msgContext.getTo().getAddress()); |
| |
| if (metadata != null) { |
| SOAPEnvelope envelope = newmsgContext.getEnvelope(); |
| if (envelope == null) { |
| SOAPFactory fac = getSOAPFactory(msgContext); |
| envelope = fac.getDefaultEnvelope(); |
| } |
| |
| OMElement result = metadata.toOM(); |
| if (result != null) { |
| AxisService service = msgContext.getAxisService(); |
| result.declareNamespace(service.getTargetNamespace(), |
| service.getTargetNamespacePrefix()); |
| envelope.getBody().addChild(result); |
| } |
| |
| newmsgContext.setEnvelope(envelope); |
| } |
| // AxisService service = msgContext.getAxisService(); |
| |
| } catch (Exception e) { |
| log.info(e); |
| if (e instanceof MexException) { |
| throw (MexException) e; |
| } |
| throw new MexException(e); |
| } |
| |
| } |
| |
| |
| /* |
| * Handle GetMetadata Request |
| * Interprete GetMetadata request and process request. |
| * @returns Metadata object |
| */ |
| private Metadata handleRequest(MessageContext msgContext) throws AxisFault { |
| Metadata metadata = null; |
| SOAPEnvelope envelope = msgContext.getEnvelope(); |
| |
| SOAPBody body = envelope.getBody(); |
| OMElement aReq = body.getFirstChildWithName(new QName( |
| MexConstants.Spec_2004_09.NS_URI, |
| MexConstants.SPEC.GET_METADATA)); |
| |
| List metadata_request_list; |
| if (aReq != null) { |
| mexNamespaceValue = MexConstants.Spec_2004_09.NS_URI; |
| metadata_request_list = determineMetadataTypes(aReq); |
| |
| } else { |
| throw new MexException("Invalid Metadata request"); |
| } |
| |
| metadata = processRequest(metadata_request_list, msgContext, aReq); |
| |
| return metadata; |
| } |
| |
| /* |
| * Process the requests |
| * |
| * @param metadata_request_list list of mex Dialect for requesting data |
| * @msgContext MessageContext |
| * @aReq GetMetadata request |
| */ |
| |
| public Metadata processRequest(List metadata_request_list, |
| MessageContext msgContext, OMElement aReq) throws MexException { |
| |
| // Instantiate Metadata instance to build the WS-Mex Metadata element |
| SOAPEnvelope envelope = msgContext.getEnvelope(); |
| String soapNamespaceURI = envelope.getNamespace().getNamespaceURI(); |
| SOAPFactory factory = MexUtil.getSOAPFactory(soapNamespaceURI); |
| |
| Metadata metadata = new Metadata(factory, mexNamespaceValue); |
| DataRetrievalRequest requestOptions = new DataRetrievalRequest(); |
| |
| String identifier_value = null; |
| // Check if Identifier element included in request |
| OMElement dialectElem = aReq.getFirstChildWithName(new QName( |
| mexNamespaceValue, MexConstants.SPEC.DIALECT)); |
| |
| if (dialectElem != null) { |
| OMElement identifier = dialectElem.getFirstChildWithName(new QName( |
| mexNamespaceValue, MexConstants.SPEC.IDENTIFIER)); |
| |
| if (identifier != null) { |
| identifier_value = identifier.getText(); |
| if (identifier_value != null && identifier_value.length() > 0) { |
| requestOptions.putIdentifier(identifier_value); |
| } |
| } |
| } |
| |
| // Process the request and append MetadataSection to Metadata |
| // Loop through the metadata_request_list for Dialect(s)), and setup requestOptions. |
| // Basically, one requestOptions is setup for each supported outputForm for the Dialect |
| // and Identifier specified in the GetMetadata request. |
| int len = metadata_request_list.size(); |
| OutputForm[] outputforms; |
| |
| for (int i = 0; i < len; i++) { // metadata request |
| |
| String dialect = ""; |
| try { |
| dialect = (String) metadata_request_list.get(i); |
| |
| requestOptions.putDialect(dialect); |
| |
| outputforms = MexUtil.determineOutputForm(dialect, axisConfigMEXParm, serviceConfigMEXParm); |
| // Loop to call AxisService::getData API to retrieve data |
| // for the Dialect and Identifier(if specified) in the request |
| // for each |
| // supported output form. |
| |
| for (int j = 0; j < outputforms.length; j++) { // output form |
| requestOptions.putOutputForm(outputforms[j]); |
| |
| Data[] result = msgContext.getAxisService().getData(requestOptions, |
| msgContext); |
| |
| ArrayList sections = processData(result, outputforms[j], dialect, |
| identifier_value, factory); |
| metadata.addMetadatSections(sections); |
| } |
| |
| } catch (DataRetrievalException e) { |
| log.error("Data Retrieval exception detected for dialect, " + dialect, e); |
| |
| throw new MexException(e); |
| } catch (Throwable e) { |
| |
| log.error("Throwable detected for dialect, " + dialect , e); |
| e.printStackTrace(); |
| |
| throw new MexException(e); |
| } |
| |
| } |
| return metadata; |
| } |
| |
| /* |
| * Create MetadataSection for each Data element, and add the |
| * MetadataSections to Metadata. |
| */ |
| private ArrayList processData(Data[] data, OutputForm outputForm, |
| String dialect, String identifier_value, SOAPFactory factory) throws MexException { |
| MetadataSection section=null; |
| ArrayList sections = new ArrayList(); |
| if (data == null || data.length == 0) { |
| if (log.isDebugEnabled()) |
| log |
| .debug("No result was returned from getData request for dialect," |
| + dialect |
| + " Form: " |
| + outputForm.getType() |
| + ". No MetadataSection will be added!"); |
| |
| } else { |
| for (int k = 0; k < data.length; k++) { |
| |
| section = createMetadataSection(outputForm, data[k].getData(), |
| factory, mexNamespaceValue); |
| |
| section.setDialect(dialect); |
| identifier_value = data[k].getIdentifier(); |
| |
| if (identifier_value != null) { |
| section.setIdentifier(identifier_value); |
| } |
| sections.add(section); |
| |
| } |
| } |
| return sections; |
| } |
| |
| private MetadataSection createMetadataSection(OutputForm outputForm, |
| Object result, SOAPFactory factory, String mexNamespaceValue) |
| throws MexOMException { |
| MetadataSection section = new MetadataSection(factory, |
| mexNamespaceValue); |
| |
| if (outputForm == OutputForm.INLINE_FORM) |
| section.setinlineData(result); |
| else if (outputForm == OutputForm.LOCATION_FORM) |
| section.setLocation(new Location(factory, mexNamespaceValue, |
| (String) result)); |
| else if (outputForm == OutputForm.REFERENCE_FORM) { |
| MetadataReference ref = new MetadataReference(factory, |
| mexNamespaceValue); |
| |
| ref.setEPR((OMElement) result); |
| section.setMetadataReference(ref); |
| } else { |
| |
| section.setinlineData((OMElement) result); |
| } |
| |
| return section; |
| } |
| |
| /* |
| * Traverse and interprete the GetMetadata OMElement for Dialect element |
| * that specified in the request. @returns a List with Dialect(s) of |
| * metadata requested. |
| * |
| */ |
| private List determineMetadataTypes(OMElement aReq) { |
| List metadata_request_list = new ArrayList(); |
| |
| boolean allTypes = false; |
| |
| OMElement dialect = aReq.getFirstChildWithName(new QName(mexNamespaceValue, |
| MexConstants.SPEC.DIALECT)); |
| if (dialect != null) { |
| String dialectText = dialect.getText(); |
| if (dialectText != null && dialectText.length() > 0) { |
| metadata_request_list.add(dialectText.trim()); |
| } else { |
| allTypes = true; |
| } |
| } else { |
| allTypes = true; |
| } |
| |
| if (allTypes) { // retrieve all metadata |
| metadata_request_list.add(MexConstants.SPEC.DIALECT_TYPE_POLICY); |
| metadata_request_list.add(MexConstants.SPEC.DIALECT_TYPE_SCHEMA); |
| metadata_request_list.add(MexConstants.SPEC.DIALECT_TYPE_WSDL); |
| } |
| return metadata_request_list; |
| } |
| |
| |
| private void check_MEX_disabled (Parameter mexConfig) throws MexDisabledException{ |
| if (MexUtil.isMexDisabled(mexConfig)){ |
| throw new MexDisabledException("'metadataexchange' parameter configured to disable MEX for the service."); |
| } |
| } |
| } |