001    /**
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    package org.apache.geronimo.connector.outbound;
018    
019    import java.io.Externalizable;
020    import java.io.IOException;
021    import java.io.InvalidObjectException;
022    import java.io.ObjectInput;
023    import java.io.ObjectOutput;
024    import java.io.ObjectStreamException;
025    import java.io.Serializable;
026    
027    import javax.resource.spi.ConnectionManager;
028    import javax.security.auth.Subject;
029    
030    import org.apache.geronimo.connector.outbound.connectionmanagerconfig.PoolingSupport;
031    import org.apache.geronimo.connector.outbound.connectionmanagerconfig.TransactionSupport;
032    import org.apache.geronimo.connector.outbound.connectiontracking.ConnectionTracker;
033    import org.apache.geronimo.gbean.AbstractName;
034    import org.apache.geronimo.gbean.GBeanInfo;
035    import org.apache.geronimo.gbean.GBeanInfoBuilder;
036    import org.apache.geronimo.gbean.GBeanLifecycle;
037    import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
038    import org.apache.geronimo.kernel.GBeanNotFoundException;
039    import org.apache.geronimo.kernel.Kernel;
040    import org.apache.geronimo.kernel.KernelRegistry;
041    import org.apache.geronimo.kernel.proxy.ProxyManager;
042    import org.apache.geronimo.security.ContextManager;
043    import org.apache.geronimo.transaction.manager.RecoverableTransactionManager;
044    
045    /**
046     * @version $Revision: 706640 $
047     */
048    public class GenericConnectionManagerGBean extends GenericConnectionManager implements GBeanLifecycle, Serializable, Externalizable {
049        private Kernel kernel;
050        private AbstractName abstractName;
051        //externalizable format version
052        private static final int VERSION = 1;
053    
054        public GenericConnectionManagerGBean() {
055            super();
056            kernel = null;
057            abstractName = null;
058        }
059    
060        public GenericConnectionManagerGBean(TransactionSupport transactionSupport,
061                                             PoolingSupport pooling,
062                                             boolean containerManagedSecurity,
063                                             ConnectionTracker connectionTracker,
064                                             RecoverableTransactionManager transactionManager,
065                                             String objectName,
066                                             AbstractName abstractName,
067                                             ClassLoader classLoader,
068                                             Kernel kernel) {
069            super(transactionSupport, pooling, getSubjectSource(containerManagedSecurity), connectionTracker, transactionManager, objectName, classLoader);
070            this.kernel = kernel;
071            this.abstractName = abstractName;
072        }
073    
074        public ConnectionManager getConnectionManager() {
075            ConnectionManager unproxied = super.getConnectionManager();
076            ProxyManager pm = kernel.getProxyManager();
077            if (pm.isProxy(unproxied)) {
078                return unproxied;
079            } else {
080                return (ConnectionManager) pm.createProxy(kernel.getAbstractNameFor(unproxied), unproxied.getClass().getClassLoader());
081            }
082        }
083    
084        private static SubjectSource getSubjectSource(boolean containerManagedSecurity) {
085            if (containerManagedSecurity) {
086                return new SubjectSource() {
087                    public Subject getSubject() {
088                        return ContextManager.getNextCaller();
089                    }
090                };
091            } else {
092                return null;
093            }
094        }
095    
096        private Object readResolve() throws ObjectStreamException {
097            try {
098                return kernel.getGBean(abstractName);
099            } catch (GBeanNotFoundException e) {
100                throw (ObjectStreamException) new InvalidObjectException("Could not locate connection manager gbean").initCause(e);
101            }
102        }
103    
104        public void writeExternal(ObjectOutput out) throws IOException {
105            out.writeInt(VERSION);
106            out.writeObject(kernel.getKernelName());
107            out.writeObject(abstractName);
108        }
109    
110        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
111            int version = in.readInt();
112            if (version != VERSION) {
113                throw new IOException("Wrong version, expected " + VERSION + ", got: " + version);
114            }
115            String kernelName = (String) in.readObject();
116            kernel = KernelRegistry.getKernel(kernelName);
117            if (kernel == null) {
118                kernel = KernelRegistry.getSingleKernel();
119            }
120            if (kernel == null) {
121                throw new IOException("No kernel named: '" + kernelName + "' found");
122            }
123            abstractName = (AbstractName) in.readObject();
124        }
125    
126        public static final GBeanInfo GBEAN_INFO;
127    
128        static {
129            GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(GenericConnectionManagerGBean.class, AbstractConnectionManagerGBean.GBEAN_INFO);
130    
131            infoBuilder.addAttribute("transactionSupport", TransactionSupport.class, true);
132            infoBuilder.addAttribute("pooling", PoolingSupport.class, true);
133            infoBuilder.addAttribute("containerManagedSecurity", Boolean.TYPE, true);
134    
135            infoBuilder.addAttribute("objectName", String.class, false);
136            infoBuilder.addAttribute("abstractName", AbstractName.class, false);
137            infoBuilder.addAttribute("classLoader", ClassLoader.class, false);
138            infoBuilder.addAttribute("kernel", Kernel.class, false);
139    
140            infoBuilder.addReference("ConnectionTracker", ConnectionTracker.class, NameFactory.JCA_CONNECTION_TRACKER);
141            infoBuilder.addReference("TransactionManager", RecoverableTransactionManager.class, NameFactory.JTA_RESOURCE);
142    
143    
144            infoBuilder.setConstructor(new String[]{
145                    "transactionSupport",
146                    "pooling",
147                    "containerManagedSecurity",
148                    "ConnectionTracker",
149                    "TransactionManager",
150                    "objectName",
151                    "abstractName",
152                    "classLoader",
153                    "kernel"
154            });
155    
156            GBEAN_INFO = infoBuilder.getBeanInfo();
157        }
158    
159        public static GBeanInfo getGBeanInfo() {
160            return GBEAN_INFO;
161        }
162    
163    }