0

2 つの Axis データ型 (WSDL2Java によって生成される) を相互に変換する可能性を探しています。両方の DataType は、同じ XSD からのものであるため、まったく同じ属性で構成されます。

問題は、Axis がそれらを分離されたデータ型として生成することです。

データ型1:

public static class AbstractAsynchronousResponse extends AbstractResponse implements org.apache.axis2.databinding.ADBBean {

        /*
         * This type was generated from the piece of schema that had name =
         * AbstractAsynchronousResponse Namespace URI =
         * http://www.example.org/AllCallbackTypes Namespace Prefix = ns2
         */
.........}

データ型 2:

public static class AbstractAsynchronousResponse extends AbstractResponse implements org.apache.axis2.databinding.ADBBean {

        /*
         * This type was generated from the piece of schema that had name =
         * AbstractAsynchronousResponse Namespace URI =
         * http://www.example.org/AllCallbackTypes Namespace Prefix = ns2
         */
.........}

今、私はこのようなことをしたい:

AbstractAsynchronousResponse1 response1 = new AbstractAsynchronousResponse1();
AbstractAsynchronousResponse2 response2 = (AbstractAsynchronousResponse2) response1;

解決策はありますか?

4

1 に答える 1

0

この問題を解決するために作成したメソッドを次に示します。ただし、これは本当にいいことではありませんが、機能します。

/**
     * This will cast an {@link ADBBean} implementation to another
     * {@link ADBBean}, but the Implementation will be a subClass of
     * <b>parentLocationOfSourceClass</b>.<br>
     * This only is possible because of the structure of all ADBBean
     * implementations created by <code>Axis2 ADB-Databinding</code>. If you
     * cange the Databinding you probably have to adapt this Method.
     * 
     * @param inputADBBean
     *            An ADBBean Implementation created by
     *            <code>Axis2 ADB-Databinding</code>
     * @param parentLocationOfSourceClass
     *            This is meant to be the <code>ClientStub</code> Class created
     *            by <code>Axis2 ADB-Databinding</code>. The Implementation of
     *            the <code>inputADBBean</code> has to be available with the
     *            same name in the <code>ClientStub</code>
     * @return An {@link ADBBean} implementation defined as SubClass of the
     *         <code>ClientStub</code> Class created by
     *         <code>Axis2 ADB-Databinding</code>
     * @throws Exception
     */
    public static ADBBean castADBBean(ADBBean inputADBBean, String parentLocationOfSourceClass) throws Exception {
        Class clazz = CallbackResponsePoolClient.getClassForParentLocation(inputADBBean, parentLocationOfSourceClass);
        ADBBean outputADBBean = CallbackResponsePoolClient.getInstanceForADBBean(clazz);
        for (Method method : outputADBBean.getClass().getMethods()) {
            String methodName = method.getName();
            if (methodName.startsWith("set")) {
                CallbackResponsePoolClient.logger.debug("Found a setter: " + methodName);
                String getterName = methodName.replaceFirst("set", "get");
                Object arg = inputADBBean.getClass().getMethod(getterName).invoke(inputADBBean);
                // We need to check if arg lives in the namespace:
                // org.example.www.callbackresponsepoolinterface
                // This will happen if we have nested Objects. E.g.
                // EndpointType inside of EndpointResponse
                // TODO: instanceof ADBBean could lead to problems, maybe
                // sometimes we don't want to cast an ADBBean, but I can't think
                // a scenario right now
                if (arg instanceof ADBBean) {
                    arg = CallbackResponsePoolClient.castADBBean((ADBBean) arg, parentLocationOfSourceClass);
                }
                // We also need to handle Arrays of ADBBeans. See above
                if (arg instanceof ADBBean[]) {
                    Class innputClass = ((ADBBean[]) arg).getClass().getComponentType();
                    // Better Create a new Object, because arg[0], can get you
                    // an Exception for an empty Array
                    ADBBean inputArrObj = CallbackResponsePoolClient.getInstanceForADBBean(innputClass);
                    Class outputArrClass = CallbackResponsePoolClient.getClassForParentLocation(inputArrObj, parentLocationOfSourceClass);
                    Object outputArray = Array.newInstance(outputArrClass, ((ADBBean[]) arg).length);
                    for (int i = 0; i < Array.getLength(arg); i++) {
                        Array.set(outputArray, i, CallbackResponsePoolClient.castADBBean((ADBBean) Array.get(arg, i), parentLocationOfSourceClass));
                    }
                    arg = outputArray;
                }

                method.invoke(outputADBBean, arg);
            }
        }

        return outputADBBean;
    }

    private static Class getClassForParentLocation(ADBBean inputADBBean, String parentLocationOfSourceClass) throws ClassNotFoundException {
        return Class.forName(parentLocationOfSourceClass + "$" + inputADBBean.getClass().getSimpleName());
    }

    private static ADBBean getInstanceForADBBean(Class clazz) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        Constructor constructor = clazz.getConstructor();
        return (ADBBean) constructor.newInstance();
    }
于 2012-11-26T13:47:56.167 に答える