blob: 23edcfe933881c4dd9389b4f27f21eba80d8a523 [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.axis2.context.externalize;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.xml.namespace.QName;
import org.apache.axis2.description.AxisMessage;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.AxisServiceGroup;
import org.apache.axis2.description.TransportInDescription;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.engine.Handler;
import org.apache.axis2.transport.TransportListener;
import org.apache.axis2.util.MetaDataEntry;
import org.apache.axis2.wsdl.WSDLConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Some Externalize objects must be "activated" after they are read.
* Activation normally involves associating the object with objects in the current
* runtime.
*
* ActivateUtils provides activation related utilities
*/
public class ActivateUtils {
private static final Log log = LogFactory.getLog(ActivateUtils.class);
/**
* Private Constructor
* All methods in ActivateUtils are static.
*/
private ActivateUtils() {}
/**
* Find the AxisServiceGroup object that matches the criteria
* <p/>
* <B>Note<B> the saved service group meta information may not
* match up with any of the serviceGroups that
* are in the current AxisConfiguration object.
*
* @param axisConfig The AxisConfiguration object
* @param serviceGrpClassName the class name string for the target object
* (could be a derived class)
* @param serviceGrpName the name associated with the service group
* @return the AxisServiceGroup object that matches the criteria
*/
public static AxisServiceGroup findServiceGroup(AxisConfiguration axisConfig,
String serviceGrpClassName,
String serviceGrpName) {
Iterator its = axisConfig.getServiceGroups();
while (its.hasNext()) {
AxisServiceGroup serviceGroup = (AxisServiceGroup) its.next();
String tmpSGClassName = serviceGroup.getClass().getName();
String tmpSGName = serviceGroup.getServiceGroupName();
if (tmpSGClassName.equals(serviceGrpClassName)) {
boolean found = false;
// the serviceGroupName can be null, so either both the
// service group names are null or they match
if ((tmpSGName == null) && (serviceGrpName == null)) {
found = true;
} else if ((tmpSGName != null) && (tmpSGName.equals(serviceGrpName))) {
found = true;
}
if (found) {
// trace point
if (log.isTraceEnabled()) {
log.trace("ObjectStateUtils:findServiceGroup(): returning ["
+ serviceGrpClassName + "] [" + serviceGrpName + "]");
}
return serviceGroup;
}
}
}
// trace point
if (log.isTraceEnabled()) {
log.trace("ObjectStateUtils:findServiceGroup(): [" + serviceGrpClassName + "] ["
+ serviceGrpName + "] returning [null]");
}
return null;
}
/**
* Find the AxisService object that matches the criteria
*
* @param axisConfig The AxisConfiguration object
* @param serviceClassName the class name string for the target object
* (could be a derived class)
* @param serviceName the name associated with the service
* @return the AxisService object that matches the criteria
*/
public static AxisService findService(AxisConfiguration axisConfig, String serviceClassName,
String serviceName) {
HashMap services = axisConfig.getServices();
Iterator its = services.values().iterator();
while (its.hasNext()) {
AxisService service = (AxisService) its.next();
String tmpServClassName = service.getClass().getName();
String tmpServName = service.getName();
if ((tmpServClassName.equals(serviceClassName)) && (tmpServName.equals(serviceName))) {
// trace point
if (log.isTraceEnabled()) {
log.trace("ObjectStateUtils:findService(): returning [" + serviceClassName
+ "] [" + serviceName + "]");
}
return service;
}
}
// trace point
if (log.isTraceEnabled()) {
log.trace("ObjectStateUtils:findService(): [" + serviceClassName + "] ["
+ serviceName + "] returning [null]");
}
return null;
}
/**
* Find the AxisOperation object that matches the criteria
*
* @param axisConfig The AxisConfiguration object
* @param opClassName the class name string for the target object
* (could be a derived class)
* @param opQName the name associated with the operation
* @return the AxisOperation object that matches the given criteria
*/
public static AxisOperation findOperation(AxisConfiguration axisConfig, String opClassName,
QName opQName) {
HashMap services = axisConfig.getServices();
Iterator its = services.values().iterator();
while (its.hasNext()) {
AxisService service = (AxisService) its.next();
Iterator ito = service.getOperations();
while (ito.hasNext()) {
AxisOperation operation = (AxisOperation) ito.next();
String tmpOpName = operation.getClass().getName();
QName tmpOpQName = operation.getName();
if ((tmpOpName.equals(opClassName)) && (tmpOpQName.equals(opQName))) {
// trace point
if (log.isTraceEnabled()) {
log.trace("ObjectStateUtils:findOperation(axisCfg): returning ["
+ opClassName + "] [" + opQName.toString() + "]");
}
return operation;
}
}
}
// trace point
if (log.isTraceEnabled()) {
log.trace("ObjectStateUtils:findOperation(axisCfg): [" + opClassName + "] ["
+ opQName.toString() + "] returning [null]");
}
return null;
}
/**
* Find the AxisOperation object that matches the criteria
*
* @param service The AxisService object
* @param opClassName The class name string for the target object
* (could be a derived class)
* @param opQName the name associated with the operation
* @return the AxisOperation object that matches the given criteria
*/
public static AxisOperation findOperation(AxisService service, String opClassName,
QName opQName) {
if (service == null) {
return null;
}
Iterator ito = service.getOperations();
// Previous versions of Axis2 didn't use a namespace on the operation name, so they wouldn't
// have externalized a namespace. If that's the case, only compare the localPart of the
// operation name
String namespace = opQName.getNamespaceURI();
boolean ignoreNamespace = false;
if (namespace == null || "".equals(namespace)) {
ignoreNamespace = true;
}
while (ito.hasNext()) {
AxisOperation operation = (AxisOperation) ito.next();
String tmpOpName = operation.getClass().getName();
QName tmpOpQName = operation.getName();
if ((tmpOpName.equals(opClassName)) &&
((ignoreNamespace && (tmpOpQName.getLocalPart().equals(opQName.getLocalPart())) || (tmpOpQName.equals(opQName))))) {
if (log.isTraceEnabled()) {
log.trace("ObjectStateUtils:findOperation(service): ignoreNamespace [" + ignoreNamespace
+ "] returning ["
+ opClassName + "] [" + opQName.toString() + "]");
}
return operation;
}
}
// trace point
if (log.isTraceEnabled()) {
log.trace("ObjectStateUtils:findOperation(service): ignoreNamespace [" + ignoreNamespace
+ " classname [" + opClassName + "] QName ["
+ opQName.toString() + "] returning [null]");
}
return null;
}
/**
* Find the AxisMessage object that matches the criteria
*
* @param op The AxisOperation object
* @param msgName The name associated with the message
* @param msgElementName The name associated with the message element
* @return the AxisMessage object that matches the given criteria
*/
public static AxisMessage findMessage(AxisOperation op, String msgName, String msgElementName) {
// Several kinds of AxisMessages can be associated with a particular
// AxisOperation. The kinds of AxisMessages that are typically
// accessible are associated with "in" and "out".
// There are also different kinds of AxisOperations, and each
// type of AxisOperation can have its own mix of AxisMessages
// depending on the style of message exchange pattern (mep)
if (op == null) {
// trace point
if (log.isTraceEnabled()) {
log.trace("ObjectStateUtils:findMessage(): [" + msgName + "] [" + msgElementName
+ "] returning [null] - no AxisOperation");
}
return null;
}
if (msgName == null) {
// nothing to match with, expect to match against a name
// trace point
if (log.isTraceEnabled()) {
log.trace("ObjectStateUtils:findMessage(): [" + msgName + "] [" + msgElementName
+ "] returning [null] - message name is not set");
}
return null;
}
String tmpName = null;
String tmpElementName = null;
//-------------------------------------
// first try the "out" message
//-------------------------------------
AxisMessage out = null;
try {
out = op.getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
} catch (Exception ex) {
// just absorb the exception
}
if (out != null) {
tmpName = out.getName();
QName tmpQout = out.getElementQName();
if (tmpQout != null) {
tmpElementName = tmpQout.toString();
}
}
// check the criteria for a match
boolean matching = matchMessageNames(tmpName, tmpElementName, msgName, msgElementName);
if (matching) {
// trace point
if (log.isTraceEnabled()) {
log.trace("ObjectStateUtils:findMessage(): returning OUT message [" + msgName
+ "] [" + msgElementName + "] ");
}
return out;
}
//-------------------------------------
// next, try the "in" message
//-------------------------------------
AxisMessage in = null;
try {
in = op.getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
} catch (Exception ex) {
// just absorb the exception
}
if (in != null) {
tmpName = in.getName();
QName tmpQin = in.getElementQName();
if (tmpQin != null) {
tmpElementName = tmpQin.toString();
}
} else {
tmpName = null;
tmpElementName = null;
}
// check the criteria for a match
matching = matchMessageNames(tmpName, tmpElementName, msgName, msgElementName);
if (matching) {
// trace point
if (log.isTraceEnabled()) {
log.trace("ObjectStateUtils:findMessage(): returning IN message [" + msgName
+ "] [" + msgElementName + "] ");
}
return in;
}
// if we got here, then no match was found
// trace point
if (log.isTraceEnabled()) {
log.trace("ObjectStateUtils:findMessage(): [" + msgName + "] [" + msgElementName
+ "] returning [null]");
}
return null;
}
/**
* Find the Handler object that matches the criteria
*
* @param existingHandlers The list of existing handlers and phases
* @param handlerClassName the class name string for the target object
* (could be a derived class)
* @return the Handler object that matches the criteria
*/
public static Object findHandler(List<Handler> existingHandlers, MetaDataEntry metaDataEntry) //String handlerClassName)
{
String title = "ObjectStateUtils:findHandler(): ";
String handlerClassName = metaDataEntry.getClassName();
String qNameAsString = metaDataEntry.getQNameAsString();
for (int i = 0; i < existingHandlers.size(); i++) {
if (existingHandlers.get(i) != null) {
String tmpClassName = existingHandlers.get(i).getClass().getName();
String tmpName = ((Handler) existingHandlers.get(i)).getName().toString();
if ((tmpClassName.equals(handlerClassName)) && (tmpName.equals(qNameAsString))) {
// trace point
if (log.isTraceEnabled()) {
log.trace(title + " [" + handlerClassName + "] name [" + qNameAsString
+ "] returned");
}
return (Handler) (existingHandlers.get(i));
}
}
}
// trace point
if (log.isTraceEnabled()) {
log.trace(title + " [" + handlerClassName + "] name [" + qNameAsString
+ "] was not found in the existingHandlers list");
}
return null;
}
/**
* Find the TransportListener object that matches the criteria
* <p/>
* <B>Note<B> the saved meta information may not
* match up with any of the objects that
* are in the current AxisConfiguration object.
*
* @param axisConfig The AxisConfiguration object
* @param listenerClassName the class name string for the target object
* (could be a derived class)
* @return the TransportListener object that matches the criteria
*/
public static TransportListener findTransportListener(AxisConfiguration axisConfig,
String listenerClassName) {
// TODO: investigate a better technique to match up with a TransportListener
HashMap transportsIn = axisConfig.getTransportsIn();
// get a collection of the values in the map
Collection values = transportsIn.values();
Iterator i = values.iterator();
while (i.hasNext()) {
TransportInDescription ti = (TransportInDescription) i.next();
TransportListener tl = ti.getReceiver();
String tlClassName = tl.getClass().getName();
if (tlClassName.equals(listenerClassName)) {
// trace point
if (log.isTraceEnabled()) {
log.trace("ObjectStateUtils:findTransportListener(): [" + listenerClassName
+ "] returned");
}
return tl;
}
}
// trace point
if (log.isTraceEnabled()) {
log.trace("ObjectStateUtils:findTransportListener(): returning [null]");
}
return null;
}
/**
* Compares the two collections to see if they are equivalent.
*
* @param a1 The first collection
* @param a2 The second collection
* @param strict Indicates whether strict checking is required. Strict
* checking means that the two collections must have the
* same elements in the same order. Non-strict checking
* means that the two collections must have the same
* elements, but the order is not significant.
* @return TRUE if the two collections are equivalent
* FALSE, otherwise
*/
public static boolean isEquivalent(ArrayList a1, ArrayList a2, boolean strict) {
if ((a1 != null) && (a2 != null)) {
// check number of elements in lists
int size1 = a1.size();
int size2 = a2.size();
if (size1 != size2) {
// trace point
if (log.isTraceEnabled()) {
log.trace("ObjectStateUtils:isEquivalent(ArrayList,ArrayList): FALSE - size mismatch ["
+ size1 + "] != [" + size2 + "]");
}
return false;
}
if (strict) {
// Strict checking
// The lists must contain the same elements in the same order.
return (a1.equals(a2));
} else {
// Non-strict checking
// The lists must contain the same elements but the order is not required.
Iterator i1 = a1.iterator();
while (i1.hasNext()) {
Object obj1 = i1.next();
if (!a2.contains(obj1)) {
// trace point
if (log.isTraceEnabled()) {
log.trace("ObjectStateUtils:isEquivalent(ArrayList,ArrayList): FALSE - mismatch with element ["
+ obj1.getClass().getName() + "] ");
}
return false;
}
}
return true;
}
} else if ((a1 == null) && (a2 == null)) {
return true;
} else if ((a1 != null) && (a2 == null)) {
if (a1.size() == 0) {
return true;
}
return false;
} else if ((a1 == null) && (a2 != null)) {
if (a2.size() == 0) {
return true;
}
return false;
} else {
// mismatch
// trace point
if (log.isTraceEnabled()) {
log.trace("ObjectStateUtils:isEquivalent(ArrayList,ArrayList): FALSE - mismatch in lists");
}
return false;
}
}
/**
* Compares the two collections to see if they are equivalent.
*
* @param m1 The first collection
* @param m2 The second collection
* @param strict Indicates whether strict checking is required. Strict
* checking means that the two collections must have the
* same mappings. Non-strict checking means that the
* two collections must have the same keys. In both
* cases, the order is not significant.
* @return TRUE if the two collections are equivalent
* FALSE, otherwise
*/
public static boolean isEquivalent(Map m1, Map m2, boolean strict) {
if ((m1 != null) && (m2 != null)) {
if (strict) {
// This is a strict test.
// Returns true if the given object is also a map and the two Maps
// represent the same mappings.
return (m1.equals(m2));
} else {
int size1 = m1.size();
int size2 = m2.size();
if (size1 != size2) {
return false;
}
// check the keys, ordering is not important between the two maps
Iterator it1 = m1.keySet().iterator();
while (it1.hasNext()) {
Object key1 = it1.next();
if (m2.containsKey(key1) == false) {
return false;
}
}
return true;
}
} else if ((m1 == null) && (m2 == null)) {
return true;
} else {
// mismatch
return false;
}
}
/**
* Compares the two collections to see if they are equivalent.
*
* @param l1 The first collection
* @param l2 The second collection
* @return TRUE if the two collections are equivalent
* FALSE, otherwise
*/
public static boolean isEquivalent(LinkedList l1, LinkedList l2) {
if ((l1 != null) && (l2 != null)) {
// This is a strict test.
// Returns true if the specified object is also a list,
// both lists have the same size, and all corresponding pairs
// of elements in the two lists are equal where
// they contain the same elements in the same order.
return (l1.equals(l2));
} else if ((l1 == null) && (l2 == null)) {
return true;
} else {
// mismatch
return false;
}
}
/**
* Check the first set of names for a match against
* the second set of names. These names are
* associated with AxisMessage objects. Message names
* are expected to be non-null. Element names could
* be either null or non-null.
*
* @param name1 The name for the first message
* @param elementName1 The element name for the first message
* @param name2 The name for the second message
* @param elementName2 The element name for the second message
* @return TRUE if there's a match,
* FALSE otherwise
*/
private static boolean matchMessageNames(String name1, String elementName1, String name2,
String elementName2) {
// the name for the message must exist
if ((name1 != null) && (name2 != null) && (name1.equals(name2))) {
// there's a match on the name associated with the message object
// element names need to match, including being null
if ((elementName1 == null) && (elementName2 == null)) {
// there's a match for the nulls
return true;
} else if ((elementName1 != null) && (elementName2 != null)
&& (elementName1.equals(elementName2))) {
// there's a match for the element names
return true;
} else {
// there's some mismatch
return false;
}
} else {
// either a message name is null or the names don't match
return false;
}
}
}