001    package com.mockrunner.connector;
002    
003    import java.lang.reflect.Method;
004    
005    import javax.resource.ResourceException;
006    import javax.resource.cci.InteractionSpec;
007    import javax.resource.cci.Record;
008    
009    /**
010     * Implementor for IBM environments using the
011     * Web Services Invocation Framework
012     */
013    public class WSIFInteraction implements InteractionImplementor 
014    {
015        private boolean enabled;
016        private String isClassName;
017        private String requestPartName;
018        private Object requestPart;
019        private String responsePartName;
020        private Object responsePart;
021    
022            /**
023             * @param isClassName would be com.ibm.connector2.ims.ico.IMSInteractionSpec, com.ibm.connector2.cics.ECIInteractionSpec
024             */
025            public WSIFInteraction(String isClassName,
026                                       String requestPartName,
027                                       Object requestPart,
028                                       String responsePartName,
029                                       Object responsePart) 
030        {
031                    super();
032                    this.isClassName = isClassName;
033                    this.requestPartName = requestPartName;
034                    this.requestPart = requestPart;
035                    this.responsePartName = responsePartName;
036                    this.responsePart = responsePart;
037            this.enabled = true;
038            }
039        
040        /**
041         * Enables this implementor.
042         */
043        public void enable()
044        {
045            this.enabled = true;
046        }
047        
048        /**
049         * Disables this implementor. {@link #canHandle(InteractionSpec, Record, Record)}
050         * always returns <code>false</code>, if this implementor is disabled.
051         */
052        public void disable()
053        {
054            this.enabled = false;
055        }
056    
057            public boolean canHandle(InteractionSpec interactionSpec, Record actualRequest, Record actualResponse)
058        {
059            if(!enabled) return false;
060            Class specClass = getClassNamed(interactionSpec.getClass(), isClassName);
061            if (specClass != null)
062            {
063                try
064                {
065                    Class wsifMessageClass = getClassNamed(actualRequest.getClass(), "org.apache.wsif.base.WSIFDefaultMessage");
066                    Class wsifFormatPartClass = getClassNamed(requestPart.getClass(), "com.ibm.wsif.format.jca.WSIFFormatPartImpl");
067                    if (wsifMessageClass != null && wsifFormatPartClass != null)
068                    {
069                        Class[] gopParams = new Class[1];
070                        gopParams[0] = String.class;
071                        Method gop = wsifMessageClass.getMethod("getObjectPart", gopParams);
072                        if (gop != null)
073                        {
074                            Object[] gopArgs = new Object[1];
075                            gopArgs[0] = requestPartName;
076                            Object o1 = gop.invoke(actualRequest, gopArgs);
077                            if (o1 != null)
078                            {
079                                Class[] elementsParams = new Class[0];
080                                Method elements = wsifFormatPartClass.getMethod("elements", elementsParams);
081                                if (elements != null)
082                                {
083                                    Object[] elementsArgs = new Object[0];
084                                    Object map1 = elements.invoke(requestPart, elementsArgs);
085                                    Object map2 = elements.invoke(o1, elementsArgs);
086                                    if (map1.equals(map2))
087                                    {
088                                        return true;
089                                    }
090                                }
091                            }
092                        }
093                    }
094                } 
095                catch(Exception exc)
096                {
097                    return false;
098                }
099            }
100            return false;
101        }
102    
103        /**
104         * not implemented yet.
105         */
106        public Record execute(InteractionSpec interactionSpec, Record actualRequest) throws ResourceException
107        {
108            throw new RuntimeException(this.getClass().getName() + " does not implement public Record execute(InteractionSpec, Record)");
109        }
110    
111        public boolean execute(InteractionSpec interactionSpec, Record actualRequest, Record actualResponse) throws ResourceException
112        {
113            if(!canHandle(interactionSpec, actualRequest, actualResponse)) return false;
114            try
115            {
116                Class wsifMessageClass = getClassNamed(actualRequest.getClass(), "org.apache.wsif.base.WSIFDefaultMessage");
117                Class[] sopParams = new Class[2];
118                sopParams[0] = String.class;
119                sopParams[1] = Object.class;
120                Method sop = wsifMessageClass.getMethod("setObjectPart", sopParams);
121                if (sop != null)
122                {
123                    Object[] sopArgs = new Object[2];
124                    sopArgs[0] = responsePartName;
125                    sopArgs[1] = responsePart;
126                    sop.invoke(actualResponse, sopArgs);
127                    return true;
128                }
129            } 
130            catch(Exception exc)
131            {
132                ResourceException resExc = new ResourceException("execute() failed");
133                resExc.setLinkedException(exc);
134                throw resExc;
135            }
136            return false;
137        }
138    
139        /**
140         * 
141         * @param cl
142         * @param className
143         * @return null if not found
144         */
145        private Class getClassNamed(Class cl, String className)
146        {
147            if (cl == null)
148            {
149                return null;
150            }
151            if (cl.getName().equals(className))
152            {
153                return cl;
154            }
155            Class[] classes = cl.getDeclaredClasses();
156            for (int current = 0; current < classes.length; current++)
157            {
158                Class c = classes[current];
159                if (className.equals(c.getName()))
160                {
161                    return c;
162                }
163            }
164            return getClassNamed(cl.getSuperclass(), className);
165        }
166    }
167