<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="it"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../../jacoco-resources/report.gif" type="image/gif"/><title>WASManagedRuntime.java</title><link rel="stylesheet" href="../../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../../index.html" class="el_report">Tests</a> &gt; <a href="../index.html" class="el_bundle">openjpa-kernel</a> &gt; <a href="index.source.html" class="el_package">org.apache.openjpa.ee</a> &gt; <span class="el_source">WASManagedRuntime.java</span></div><h1>WASManagedRuntime.java</h1><pre class="source lang-java linenums">/*
 * 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
 * &quot;License&quot;); 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
 * &quot;AS IS&quot; 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.openjpa.ee;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.InvalidTransactionException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.Status;
import javax.transaction.Synchronization;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.xa.XAResource;

import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.enhance.AsmAdaptor;
import org.apache.openjpa.lib.conf.Configurable;
import org.apache.openjpa.lib.conf.Configuration;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.util.InvalidStateException;
import org.apache.openjpa.util.NoTransactionException;

import serp.bytecode.BCClass;
import serp.bytecode.Project;

/**
 * {@link ManagedRuntime} implementation that allows synchronization with a
 * WebSphere managed transaction.
 *
 * &lt;P&gt;
 * WebSphere Application Server does not expose the TransactionManager to an
 * application. Instead it provides a proprietary interface to register for
 * synchronization and obtain transaction ids.
 *
 * &lt;P&gt;
 * WASManagedRuntime provides the wrapper classes needed to interact with the
 * WAS proprietary interface and the OpenJPA kernel.
 *
 * @author Kevin Sutter
 */
<span class="nc" id="L65">public class WASManagedRuntime extends AbstractManagedRuntime</span>
        implements ManagedRuntime, Configurable {

<span class="nc" id="L68">    private static final Localizer _loc =</span>
<span class="nc" id="L69">        Localizer.forPackage(WASManagedRuntime.class);</span>

<span class="nc" id="L71">    private Object _extendedTransaction = null;</span>
<span class="nc" id="L72">    private Method _getGlobalId = null;</span>
<span class="nc" id="L73">    private Method _registerSync = null;</span>
<span class="nc" id="L74">    private OpenJPAConfiguration _conf = null;</span>
<span class="nc" id="L75">    private Log _log = null;</span>

    /**
     * Gets an extendedJTATransaction from JNDI and creates a transaction
     * wrapper
     */
    @Override
    public javax.transaction.TransactionManager getTransactionManager()
        throws Exception {
<span class="nc" id="L84">        return new WASTransaction();</span>
    }

    /**
     * Transaction wrapper for WebSphere. WebSphere exposes a subset of the
     * Transaction and TransactionManager interfaces to the customer. Any
     * methods which are not exposed by WebSphere will throw an
     * IllegalStateException to the caller.
     *
     * &lt;P&gt;
     * Methods supported by WAS are
     * &lt;UL&gt;
     * &lt;LI&gt;RegisterSynchronization &lt;/LI&gt;
     * &lt;LI&gt;GetStatus&lt;/LI&gt;
     * &lt;/UL&gt;
     */
<span class="nc" id="L100">    class WASTransaction implements javax.transaction.TransactionManager,</span>
        javax.transaction.Transaction {

        @Override
        public int getStatus() throws SystemException {
            int rval;
            try {
<span class="nc bnc" id="L107" title="All 2 branches missed.">                if (getGlobalId() != null) {</span>
<span class="nc" id="L108">                    rval = Status.STATUS_ACTIVE;</span>
                } else {
<span class="nc" id="L110">                    rval = Status.STATUS_NO_TRANSACTION;</span>
                }
<span class="nc" id="L112">            } catch (Exception e) {</span>
<span class="nc" id="L113">                throw new NoTransactionException(_loc</span>
<span class="nc" id="L114">                        .get(&quot;was-transaction-id-exception&quot;)).setCause(e);</span>
<span class="nc" id="L115">            }</span>
<span class="nc" id="L116">            return rval;</span>
        }

        /**
         * Provides a Transaction wrapper. The transaction wrapper mayb only be
         * used to determine the status of the current transaction. WebSphere
         * does not allow direct control of container transactions.
         *
         * @return A WebSphere transaction wrapper.
         */
        @Override
        public Transaction getTransaction() throws SystemException {
<span class="nc" id="L128">            return this;</span>
        }

        /**
         * Register for synchronization with a WebSphere managed transaction via
         * the extendedJTATransaction interface.
         */
        @Override
        public void registerSynchronization(Synchronization arg0)
            throws IllegalStateException, RollbackException, SystemException {
<span class="nc bnc" id="L138" title="All 2 branches missed.">            if (_extendedTransaction != null) {</span>
                try {
<span class="nc" id="L140">                    _registerSync.invoke(_extendedTransaction,</span>
                        new Object[] { new WASSynchronization(arg0) });
<span class="nc" id="L142">                } catch (Exception e) {</span>
<span class="nc" id="L143">                    throw new InvalidStateException(_loc</span>
<span class="nc" id="L144">                        .get(&quot;was-reflection-exception&quot;)).setCause(e);</span>
<span class="nc" id="L145">                }</span>
            } else {
<span class="nc" id="L147">                throw new InvalidStateException(_loc.get(&quot;was-lookup-error&quot;));</span>
            }
<span class="nc" id="L149">        }</span>

        /**
         * Gets the GlobalTransaction ID of the WebSphere managed transaction.
         * If no Global Transaction is active null will be returned.
         *
         * @return Null if a global transaction is not active or if an error
         *         occurs. byte[] id if a global transaction is active.
         */
        private byte[] getGlobalId() {
            try {
<span class="nc" id="L160">                return (byte[]) _getGlobalId.invoke(_extendedTransaction, null);</span>
<span class="nc" id="L161">            } catch (Exception e) {</span>
<span class="nc" id="L162">                throw new InvalidStateException(_loc</span>
<span class="nc" id="L163">                    .get(&quot;was-reflection-exception&quot;)).setCause(e);</span>
            }
        }

        /**
         * Unimplemented, WAS does not provide this level of control. Throws an
         * IllegalStateException
         */
        @Override
        public void begin() throws NotSupportedException, SystemException {
<span class="nc" id="L173">            throw new InvalidStateException(_loc.get(&quot;was-unsupported-op&quot;,</span>
                &quot;begin&quot;));
        }

        /**
         * Unimplemented, WAS does not provide this level of control. Throws an
         * IllegalStateException
         */
        @Override
        public void commit() throws HeuristicMixedException,
            HeuristicRollbackException, IllegalStateException,
            RollbackException, SecurityException, SystemException {
<span class="nc" id="L185">            throw new InvalidStateException(_loc.get(&quot;was-unsupported-op&quot;,</span>
                &quot;commit&quot;));
        }

        /**
         * Unimplemented, WAS does not provide this level of control. Throws an
         * IllegalStateException
         */
        @Override
        public void resume(Transaction arg0) throws IllegalStateException,
            InvalidTransactionException, SystemException {
<span class="nc" id="L196">            throw new InvalidStateException(_loc.get(&quot;was-unsupported-op&quot;,</span>
                &quot;resume&quot;));
        }

        /**
         * Unimplemented, WAS does not provide this level of control. Log a
         * trace instead of throwing an exception. Rollback may be used in
         * some error paths, throwing another exception may result in the
         * original exception being lost.
         */
        @Override
        public void rollback() throws IllegalStateException, SecurityException,
            SystemException {
<span class="nc bnc" id="L209" title="All 2 branches missed.">            if (_log.isTraceEnabled()) {</span>
<span class="nc" id="L210">                _log.trace(_loc.get(&quot;was-unsupported-op&quot;, &quot;rollback&quot;));</span>
            }
<span class="nc" id="L212">        }</span>

        /**
         * Unimplemented, WAS does not provide this level of control. Log a
         * trace instead of throwing an exception. SetRollbackOnly may be used
         * in some error paths, throwing another exception may result in the
         * original exception being lost.
         */
        @Override
        public void setRollbackOnly() throws IllegalStateException,
            SystemException {
<span class="nc bnc" id="L223" title="All 2 branches missed.">            if (_log.isTraceEnabled()) {</span>
<span class="nc" id="L224">                _log.trace(_loc.get(&quot;was-unsupported-op&quot;, &quot;setRollbackOnly&quot;));</span>
            }
<span class="nc" id="L226">        }</span>

        /**
         * Unimplemented, WAS does not provide this level of control. Throws an
         * IllegalStateException
         */
        @Override
        public void setTransactionTimeout(int arg0) throws SystemException {
<span class="nc" id="L234">            throw new InvalidStateException(_loc.get(&quot;was-unsupported-op&quot;,</span>
                &quot;setTransactionTimeout&quot;));
        }

        /**
         * Unimplemented, WAS does not provide this level of control. Throws an
         * IllegalStateException
         */
        @Override
        public Transaction suspend() throws SystemException {
<span class="nc" id="L244">            throw new InvalidStateException(_loc.get(&quot;was-unsupported-op&quot;,</span>
                &quot;suspend&quot;));
        }

        /**
         * Unimplemented, WAS does not provide this level of control. Throws an
         * IllegalStateException
         */
        @Override
        public boolean delistResource(XAResource arg0, int arg1)
            throws IllegalStateException, SystemException {
<span class="nc" id="L255">            throw new InvalidStateException(_loc.get(&quot;was-unsupported-op&quot;,</span>
                &quot;delistResource&quot;));
        }

        /**
         * Unimplemented, WAS does not provide this level of control. Throws an
         * IllegalStateException
         */
        @Override
        public boolean enlistResource(XAResource arg0)
            throws IllegalStateException, RollbackException, SystemException {
<span class="nc" id="L266">            throw new InvalidStateException(_loc.get(&quot;was-unsupported-op&quot;,</span>
                &quot;enlistResource&quot;));
        }
    }

    /**
     * WASSynchronization wrapper. This class translates the WAS proprietary
     * synchronization callback methods to javax.transaction.Synchronization
     * methods.
     *
     * &lt;P&gt;
     * This class implements the
     * com.ibm.websphere.jtaextensions.SynchronizationCallback interface. Since
     * SynchronizationCallback is not available at compile time we use Serp to
     * add the interface to the class after all classes have been compiled.
     *
     * &lt;P&gt;
     * SynchronizationCallback is expected to be available whenever this class
     * is instantiated, therefore this class should only be used when running in
     * WebSphere.
     *
     * @see org.apache.openjpa.util.WASTransformer
     */
    static class WASSynchronization {

<span class="nc" id="L291">        Synchronization _sync = null;</span>

<span class="nc" id="L293">        WASSynchronization(Synchronization sync) {</span>
<span class="nc" id="L294">            _sync = sync;</span>
<span class="nc" id="L295">        }</span>

        /**
         * AfterCompletion wrapper. Translates the WAS proprietary call to a
         * javax.transaction.Synchronization call.
         */
        public void afterCompletion(int localTransactionId,
            byte[] globalTransactionId, boolean committed) {
<span class="nc bnc" id="L303" title="All 2 branches missed.">            if (_sync != null) {</span>
<span class="nc bnc" id="L304" title="All 2 branches missed.">                if (committed) {</span>
<span class="nc" id="L305">                    _sync.afterCompletion(Status.STATUS_COMMITTED);</span>
                } else {
<span class="nc" id="L307">                    _sync.afterCompletion(Status.STATUS_UNKNOWN);</span>
                }
            }
<span class="nc" id="L310">        }</span>

        /**
         * BeforeCompletion wrapper. Translates WAS proprietary call to a
         * javax.transaction.Synchronization call.
         */
        public void beforeCompletion(int arg0, byte[] arg1) {
<span class="nc bnc" id="L317" title="All 2 branches missed.">            if (_sync != null) {</span>
<span class="nc" id="L318">                _sync.beforeCompletion();</span>
            }
<span class="nc" id="L320">        }</span>
    }

    /**
     * Caches a copy of the configuration. The configuration is used to obtain
     * the logger and classloader.
     */
    @Override
    public void setConfiguration(Configuration conf) {
<span class="nc" id="L329">        _conf = (OpenJPAConfiguration) conf;</span>
<span class="nc" id="L330">        _log = _conf.getLog(OpenJPAConfiguration.LOG_RUNTIME);</span>
<span class="nc" id="L331">    }</span>

    /**
     * EndConfiguration stub.
     */
    @Override
    public void endConfiguration() {
        try {
<span class="nc" id="L339">            Context ctx = new InitialContext();</span>
            try {
<span class="nc" id="L341">                _extendedTransaction =</span>
<span class="nc" id="L342">                    ctx.lookup(&quot;java:comp/websphere/ExtendedJTATransaction&quot;);</span>
            } finally {
<span class="nc" id="L344">                ctx.close();</span>
            }

<span class="nc" id="L347">            Class extendedJTATransaction = Class.forName(</span>
                    &quot;com.ibm.websphere.jtaextensions.ExtendedJTATransaction&quot;);
<span class="nc" id="L349">            Class synchronizationCallback = Class.forName(</span>
                    &quot;com.ibm.websphere.jtaextensions.SynchronizationCallback&quot;);

<span class="nc" id="L352">            _registerSync = extendedJTATransaction.getMethod(</span>
                    &quot;registerSynchronizationCallbackForCurrentTran&quot;,
                    new Class[] { synchronizationCallback });
<span class="nc" id="L355">            _getGlobalId = extendedJTATransaction.</span>
<span class="nc" id="L356">                getMethod(&quot;getGlobalId&quot;, null);</span>
<span class="nc" id="L357">        } catch (Exception e) {</span>
<span class="nc" id="L358">            throw new InvalidStateException(_loc</span>
<span class="nc" id="L359">                .get(&quot;was-reflection-exception&quot;), e).setFatal(true);</span>
<span class="nc" id="L360">        }</span>
<span class="nc" id="L361">    }</span>

    /**
     * StartConfiguration stub.
     */
    @Override
    public void startConfiguration() {
        // Nothing to do
<span class="nc" id="L369">    }</span>

    /**
     * Class that will be modified
     */
    static final String CLASS =
        &quot;org.apache.openjpa.ee.WASManagedRuntime$WASSynchronization&quot;;

    /**
     * Interface which will be added
     */
    static final String INTERFACE =
        &quot;com.ibm.websphere.jtaextensions.SynchronizationCallback&quot;;

    public static void main(String[] args)
        throws IOException {
<span class="nc" id="L385">        Project project = new Project();</span>

<span class="nc" id="L387">        InputStream in = WASManagedRuntime.class.getClassLoader()</span>
<span class="nc" id="L388">            .getResourceAsStream(CLASS.replace('.', '/') + &quot;.class&quot;);</span>
<span class="nc" id="L389">        BCClass bcClass = project.loadClass(in);</span>

<span class="nc" id="L391">        String [] interfaces = bcClass.getInterfaceNames();</span>

<span class="nc bnc" id="L393" title="All 2 branches missed.">        if(interfaces != null) {</span>
<span class="nc bnc" id="L394" title="All 2 branches missed.">        	for(int i = 0; i &lt; interfaces.length; i++) {</span>
<span class="nc bnc" id="L395" title="All 2 branches missed.">        		if(interfaces[i].equals(INTERFACE)) {</span>
<span class="nc" id="L396">        			return;</span>
        		}
        	}
        }
<span class="nc" id="L400">        bcClass.declareInterface(INTERFACE);</span>
<span class="nc" id="L401">        AsmAdaptor.write(bcClass);</span>
<span class="nc" id="L402">    }</span>

    @Override
    public void setRollbackOnly(Throwable cause)
        throws Exception {
        // there is no generic support for setting the rollback cause
<span class="nc" id="L408">        getTransactionManager().getTransaction().setRollbackOnly();</span>
<span class="nc" id="L409">    }</span>

    @Override
    public Throwable getRollbackCause()
        throws Exception {
        // there is no generic support for setting the rollback cause
<span class="nc" id="L415">        return null;</span>
    }
}
</pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.4.201905082037</span></div></body></html>
{'avg_line_length': 46.94976076555024, 'max_line_length': 1170, 'alphanum_fraction': 0.6357707006369426, 'licenses': ['Apache-2.0'], 'repository_name': 'dantealighieri1265/openjpa', 'path': 'tests/target/site/jacoco-aggregate/openjpa-kernel/org.apache.openjpa.ee/WASManagedRuntime.java.html', 'size': 19625, 'lang': 'HTML'}