Package com.sun.enterprise.ee.web.sessmgmt

Source Code of com.sun.enterprise.ee.web.sessmgmt.ReplicationAttributeStore

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.  If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/

package com.sun.enterprise.ee.web.sessmgmt;

import com.sun.appserv.ha.spi.BackingStore;
import com.sun.appserv.ha.spi.BackingStoreException;
import com.sun.appserv.ha.util.CompositeMetadata;
import com.sun.appserv.ha.util.SessionAttributeMetadata;
import com.sun.appserv.ha.util.Metadata;
import com.sun.enterprise.ee.web.authenticator.ReplicationSingleSignOn;
import com.sun.enterprise.security.web.SingleSignOn;
import com.sun.enterprise.security.web.SingleSignOnEntry;
import org.apache.catalina.*;
import org.apache.catalina.session.*;

import java.io.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
*
* @author Larry White
*/
public class ReplicationAttributeStore extends ReplicationStore implements HAStorePoolElement {
   
    public final static String LOGGER_MEM_REP
        = ReplicationState.LOGGER_MEM_REP;   
   
    /**
     * The logger to use for logging ALL web container related messages.
     */
    //protected static final Logger _logger
    //    = LogDomains.getLogger(LogDomains.WEB_LOGGER);
    private static final Logger _logger
        = Logger.getLogger(LOGGER_MEM_REP);   
   
    protected final static String MODE_WEB
        = ReplicationState.MODE_WEB;
    protected final static String MESSAGE_QUERY_RESULT
        = ReplicationState.MESSAGE_QUERY_RESULT;
   
    /** Creates a new instance of ReplicationAttributeStore */
    public ReplicationAttributeStore() {
        setLogLevel();
    }
   
    // HAStorePoolElement methods begin
   
    /**
     * Save the specified Session into this Store.  Any previously saved
     * information for the associated session identifier is replaced.
     *
     * @param session Session to be saved
     *
     * @exception IOException if an input/output error occurs
     */   
    public void valveSave(Session session) throws IOException {
        HASession haSess = (HASession)session;
        if( haSess.isPersistent() && !haSess.isDirty() ) {
            this.updateLastAccessTime(session);
        } else {
            this.doValveSave(session);
            haSess.setPersistent(true);
        }
        haSess.setDirty(false);       
    }
   
    // Store method begin
   
    /**
     * Save the specified Session into this Store.  Any previously saved
     * information for the associated session identifier is replaced.
     *
     * @param session Session to be saved
     *
     * @exception IOException if an input/output error occurs
     */   
    public void save(Session session) throws IOException {       
        HASession haSess = (HASession)session;
        if( haSess.isPersistent() && !haSess.isDirty() ) {
            this.updateLastAccessTime(session);
        } else {
            this.doSave(session);
            haSess.setPersistent(true);
        }
        haSess.setDirty(false);       
    }
   
    //methods copied from ReplicationStore
    //must be modified for modified-attribute usage
   
    /**
     * Save the specified Session into this Store.  Any previously saved
     * information for the associated session identifier is replaced.
     *
     * @param session Session to be saved
     *
     * @exception IOException if an input/output error occurs
     */   
    public void doValveSave(Session session) throws IOException {
        if(_logger.isLoggable(Level.FINE)) {
            _logger.fine("ReplicationAttributeStore>>doValveSave:valid =" + ((StandardSession)session).getIsValid());
            _logger.fine("ReplicationAttributeStore>>valveSave:ssoId=" + ((HASession)session).getSsoId());                   
        }        
       
        // begin 6470831 do not save if session is not valid
        if( !((StandardSession)session).getIsValid() ) {
            return;
        }
        // end 6470831       
        ModifiedAttributeHASession modAttrSession
                = (ModifiedAttributeHASession)session;
        String userName = "";
        if(session.getPrincipal() !=null){
            userName = session.getPrincipal().getName();
            ((BaseHASession)session).setUserName(userName);
        }       
        ReplicationManagerBase mgr
            = (ReplicationManagerBase)this.getManager();
        BackingStore replicator = mgr.getCompositeBackingStore();
        if(_logger.isLoggable(Level.FINE)) {
            _logger.fine("ReplicationAttributeStore>>save: replicator: " + replicator);                   
        }        
        CompositeMetadata compositeMetadata
            = createCompositeMetadata(modAttrSession);
               
        try {       
            replicator.save(session.getIdInternal(), //id
                    compositeMetadata, !((HASession) session).isPersistent());
            modAttrSession.resetAttributeState();
            //postSaveUpdate(modAttrSession);
        } catch (BackingStoreException ex) {
            //FIXME
        }
    }

    public ReplicationState getTransmitState(Session session) throws IOException {
        ReplicationManagerBase mgr
            = (ReplicationManagerBase)this.getManager();
        BackingStore replicator = mgr.getBackingStore();
        if(!(replicator instanceof JxtaBackingStoreImpl)) {
            return null;
        }
        JxtaBackingStoreImpl jxtaReplicator = (JxtaBackingStoreImpl)replicator;
        ReplicationState transmitState = null;
        ModifiedAttributeHASession modAttrSession
                = (ModifiedAttributeHASession)session;
        String userName = "";
        if(session.getPrincipal() !=null){
            userName = session.getPrincipal().getName();
            ((BaseHASession)session).setUserName(userName);
        }
        CompositeMetadata compositeMetadata
            = createCompositeMetadata(modAttrSession);
        String beKey = session.getBeKey();
        if(beKey != null) {
            compositeMetadata.setBeKey(beKey);
        }
        //need this here because save not called
        compositeMetadata.setOwningInstanceName(ReplicationUtil.getInstanceName());
        try {
            transmitState = jxtaReplicator.getCompositeTransmitState(session.getIdInternal(), compositeMetadata);
        } catch (BackingStoreException ex) {}
        return transmitState;
    }
   
    /**
     * Save the specified Session into this Store.  Any previously saved
     * information for the associated session identifier is replaced.
     *
     * @param session Session to be saved
     *
     * @exception IOException if an input/output error occurs
     */   
    public void doSave(Session session) throws IOException {
        // begin 6470831 do not save if session is not valid
        if( !((StandardSession)session).getIsValid() ) {
            return;
        }
        // end 6470831       
        ModifiedAttributeHASession modAttrSession
                = (ModifiedAttributeHASession)session;
        ReplicationManagerBase mgr
            = (ReplicationManagerBase)this.getManager();
        BackingStore replicator = mgr.getCompositeBackingStore();
        if(_logger.isLoggable(Level.FINE)) {
            _logger.fine("ReplicationAttributeStore>>doSave: replicator: " + replicator);                   
        }        
        CompositeMetadata compositeMetadata
            = createCompositeMetadata(modAttrSession);
               
        try {       
            replicator.save(session.getIdInternal(), //id
                    compositeMetadata, !((HASession) session).isPersistent());
            modAttrSession.resetAttributeState();
            //postSaveUpdate(modAttrSession);
        } catch (BackingStoreException ex) {
            //FIXME
        }
    }
   
    private BackingStore getCompositeBackingStore() {
        ReplicationManagerBase mgr
                = (ReplicationManagerBase) this.getManager();
        BackingStore backingStore = mgr.getCompositeBackingStore();
        return backingStore;
    }

    /**
    * Load and return the Session associated with the specified session
    * identifier from this Store, without removing it.  If there is no
    * such stored Session, return <code>null</code>.
    *
    * @param id Session identifier of the session to load
    *
    * @exception ClassNotFoundException if a deserialization error occurs
    * @exception IOException if an input/output error occurs
    */
    public Session load(String id) throws ClassNotFoundException, IOException {
        return load(id, null);
    }

    public Session load(String id, String version)
            throws ClassNotFoundException, IOException {
        try {
            CompositeMetadata metaData =
                    (CompositeMetadata) getCompositeBackingStore().load(id, version);
            if(_logger.isLoggable(Level.FINE)) {
                _logger.fine("ReplicationAttributeStore>>load:id=" + id + ", metaData=" + metaData);
            }
            Session session = getSession(metaData);
            validateAndSave(session);
            return session;
        } catch (BackingStoreException ex) {
            IOException ex1 =
                    (IOException) new IOException("Error during load: " + ex.getMessage()).initCause(ex);
            throw ex1;
        }
    }

    private void validateAndSave(Session session) throws IOException {
        if (session != null) {
            if (_logger.isLoggable(Level.FINE)) {
                _logger.fine("ReplicationAttributeStore>>validateAndSave saving " +
                        "the session after loading it. Session=" + session);
            }
            //save session - save will reset dirty to false
            ((HASession) session).setDirty(true);
            valveSave(session); // TODO :: revisit this for third party backing stores;
        }
        if (session != null) {
            ((HASession) session).setDirty(false);
            ((HASession) session).setPersistent(false);
        }
    }

    /**
    * Load and return the Session associated with the specified session
    * identifier from this Store, without removing it.  If there is no
    * such stored Session, return <code>null</code>.
    *
    * @param id Session identifier of the session to load
    *
    * @exception ClassNotFoundException if a deserialization error occurs
    * @exception IOException if an input/output error occurs
    */
    public Metadata __load(String id, String version) throws BackingStoreException {
        CompositeMetadata result = null;
        if(id == null) {
            return result;
        }
        ReplicationManagerBase repMgr =
            (ReplicationManagerBase)this.getManager();
        //ReplicationState localCachedState = repMgr.getFromReplicationCache(id);
        ReplicationState localCachedState = repMgr.transferFromReplicationCache(id);        
        if(_logger.isLoggable(Level.FINE)) {
            _logger.fine("ReplicationAttributeStore>>__load:localCachedState=" + localCachedState);
        }
        //check if we got a hit from our own replica cache
        //and if so return it immediately
        if(version != null && localCachedState != null) {
            long versionLong = ReplicationUtil.parseLong(version);
            if(localCachedState.getVersion() == versionLong) {
                return ReplicationState.createCompositeMetadataFrom(localCachedState);
            }           
        }       
        ReplicationState broadcastResultState = findSessionViaBroadcast(id, version);
        ReplicationState bestState
            = ReplicationState.getBestResult(localCachedState, broadcastResultState);
        if(_logger.isLoggable(Level.FINE)) {
            _logger.fine("ReplicationAttributeStore>>__load:broadcastResultState from broadcast=" +
                    broadcastResultState + ", bestState = " + bestState);
        }
        result = ReplicationState.createCompositeMetadataFrom(bestState);
        return result;
    }
   
    private ReplicationState findSessionViaBroadcast(String id, String version)
            throws BackingStoreException{
        if(_logger.isLoggable(Level.FINER)) {
            _logger.entering("ReplicationAttributeStore",
                             "findSessionViaBroadcast",
                             new Object[]{id, version});                      
        }         
        ReplicationManagerBase mgr
            = (ReplicationManagerBase)this.getManager();
        BackingStore replicator = mgr.getCompositeBackingStore();
        JxtaBackingStoreImpl jxtaReplicator = null;
        if(replicator instanceof JxtaBackingStoreImpl) {
            jxtaReplicator = (JxtaBackingStoreImpl)replicator;
        }       
        if(_logger.isLoggable(Level.FINE)) {
            _logger.fine("ReplicationAttributeStore>>findSessionViaBroadcast: replicator: " + replicator);                      
        }
        ReplicationState queryResult = jxtaReplicator != null ?
                jxtaReplicator.__load(id, version) : null;
        return queryResult;
    }
   
    /**
    * Given a byte[] containing session data, return a session
    * object
    * note we use the trunkState to get the basic session
    * this over-rides the inherited getSession method behavior
    *
    * @param replicationState
    *   The byte[] with the session data
    *
    * @return
    *   A newly created session for the given session data, and associated
    *   with this Manager
    */
    @Override
    public Session getSession(ReplicationState replicationState) throws IOException {
        if (replicationState == null || replicationState.getState() == null) {
            return null;
        } else {
            return getSession(ReplicationState.createCompositeMetadataFrom(replicationState));
        }
    }

    public Session getSession(CompositeMetadata metadata)
        throws IOException
    {
        if (metadata == null || metadata.getState() == null) {
            return null;
        }
        byte[] state = metadata.getState();
        Session _session = null;
        BufferedInputStream bis = null;
        ByteArrayInputStream bais = null;
        Loader loader = null;   
        ClassLoader classLoader = null;
        ObjectInputStream ois = null;
        Container container = manager.getContainer();
        java.security.Principal pal=null; //MERGE chg added
        String ssoId = null;
        long version = 0L;
        IOUtilsCaller utilsCaller = null;
           
        try
        {
            bais = new ByteArrayInputStream(state);
            bis = new BufferedInputStream(bais);
           
            //Get the username, ssoId from metadata
            //ssoId = metadata.getSsoId();
            ssoId = metadata.getStringExtraParam();
            version = metadata.getVersion();
            //debug("ReplicationStore.getSession()  id="+id+"  username ="+username+";");   

            if(_logger.isLoggable(Level.FINEST)) {
                _logger.finest("loaded session from replicationstore, length = "+state.length);
            }
            if (container != null) {
                loader = container.getLoader();
            }

            if (loader != null) {
                classLoader = loader.getClassLoader();
            }
           
            //Bug 4832603 : EJB Reference Failover
            //HERCULES FIXME: for now reverting back
            //need to look at new EJBUtils and related serialization code
            /*
          if (classLoader != null) {
            ois = new CustomObjectInputStream(bis, classLoader);
          }
          else {
            ois = new ObjectInputStream(bis);
          }
         
            //ois = EJBUtils.getInputStream(bis, classLoader, true, true);
            //end - Bug 4832603 
             */         
            if (classLoader != null) {
                if( (utilsCaller = this.getWebUtilsCaller()) != null) {
                    try {
                        ois = utilsCaller.createObjectInputStream(bis, true, classLoader);
                    } catch (Exception ex) {}
                }
            }
            if (ois == null) {
                ois = new ObjectInputStream(bis);
            }
           
            if(ois != null) {
                try {
                    _session = readSession(manager, ois);
                }
                finally {
                    if (ois != null) {
                        try {
                            ois.close();
                            bis = null;
                        }
                        catch (IOException e) {
                        }
                    }
                }
            }
        }
        catch(ClassNotFoundException e)
        {
            IOException ex1 = (IOException) new IOException(
                    "Error during deserialization: " + e.getMessage()).initCause(e);
            throw ex1;
        }
        catch(IOException e)
        {
            //System.err.println("getSession IOException :"+e.getMessage());
            throw e;
        }
        String username = ((HASession)_session).getUserName();
        if((username !=null) && (!username.equals("")) && _session.getPrincipal() == null) {
            if (_debug > 0) {
                debug("Username retrieved is "+username);
            }
            pal = ((com.sun.web.security.RealmAdapter)container.getRealm()).createFailOveredPrincipal(username);
            if (_debug > 0) {
                debug("principal created using username  "+pal);
            }
            if(pal != null) {
                _session.setPrincipal(pal);
                if (_debug > 0) {
                    debug("getSession principal="+pal+" was added to session="+_session);
                }               
            }           
        }
        //--SRI       
       
        _session.setNew(false);
        if(_logger.isLoggable(Level.FINE)) {
            _logger.fine("ReplicationAttributeStore>>ssoId=" + ssoId);                      
        }       
        ((BaseHASession)_session).setSsoId(ssoId);       
        if((ssoId !=null) && (!ssoId.equals("")))
            associate(ssoId, _session);
        ((HASession)_session).setVersion(version);
        ((HASession)_session).setDirty(false);
       
        //now load entries from deserialized entries collection
        ((ModifiedAttributeHASession)_session).clearAttributeStates();
/*
        byte[] entriesState = metadata.getState();
        Collection entries = null;
        if(entriesState != null) {
            entries = this.deserializeStatesCollection(entriesState);
            loadAttributes((ModifiedAttributeHASession)_session, entries);
        }
*/
        loadAttributes((ModifiedAttributeHASession)_session, metadata.getEntries());
        return _session;
    }
   
    //FIXME might not be needed - can make a no-ope
    protected void associate(String ssoId, Session _session) {
        if (_debug > 0) {
            debug("Inside associate() -- HAStore");
        }
        Container parent = manager.getContainer();
        SingleSignOn sso = null;
        while ((sso == null) && (parent != null)) {
            if (_debug > 0) {
                 debug("Inside associate()  while loop -- HAStore");
            }
        if (!(parent instanceof Pipeline)) {
            if (_debug > 0) {
                 debug("Inside associate()  parent instanceof Pipeline -- HAStore");
            }
            parent = parent.getParent();
            continue;
        }
        Valve valves[] = ((Pipeline) parent).getValves();
        for (int i = 0; i < valves.length; i++) {
            if (valves[i] instanceof SingleSignOn) {
                 if (_debug > 0) {
                    debug("Inside associate()  valves[i] instanceof SingleSignOn -- HAStore");
                 }
                 sso = (SingleSignOn) valves[i];
                 break;
             }
        }
        if (sso == null)
            parent = parent.getParent();
        }
        if (sso != null) {
            if (_debug > 0) {
                debug("Inside associate() sso != null");
            }
            //SingleSignOnEntry ssoEntry = ((ReplicationSingleSignOn)sso).lookup(ssoId);
            SingleSignOnEntry ssoEntry = ((ReplicationSingleSignOn)sso).lookupEntry(ssoId);
                if(_logger.isLoggable(Level.FINEST)) {
                    _logger.finest("Inside associate() ssoEntry = "+ssoEntry);
                }
                if(ssoEntry!=null)
                    ssoEntry.addSession(sso, _session);
        }

    }  
   
    //metadata related
   
    private void postSaveUpdate(ModifiedAttributeHASession modAttrSession) {
        if(_logger.isLoggable(Level.FINE)) {
            _logger.fine("ReplicationAttributeStore>>postSaveUpdate");                      
        }
        ArrayList addedAttrs = modAttrSession.getAddedAttributes();
        ArrayList modifiedAttrs = modAttrSession.getModifiedAttributes();
        ArrayList deletedAttrs = modAttrSession.getDeletedAttributes();
        //printAttrList("ADDED", addedAttrs);
        //printAttrList("MODIFIED", modifiedAttrs);
        //printAttrList("DELETED", deletedAttrs);

        postProcessSetAttrStates(modAttrSession, addedAttrs);
        postProcessSetAttrStates(modAttrSession, modifiedAttrs);
       
    }
   
    private void postProcessSetAttrStates(ModifiedAttributeHASession modAttrSession, ArrayList attrsList) {
        for(int i=0; i<attrsList.size(); i++) {
            String nextStateName = (String)attrsList.get(i);
            modAttrSession.setAttributeStatePersistent(nextStateName, true);
            modAttrSession.setAttributeStateDirty(nextStateName, false);
        }
    }
   
    private CompositeMetadata createCompositeMetadata(ModifiedAttributeHASession modAttrSession) {
       
        byte[] trunkState = null;
        try {
            trunkState = this.getByteArray(modAttrSession);
        } catch(IOException ex) {
            //no op
        }
        if(_logger.isLoggable(Level.FINE)) {
            _logger.fine("ReplicationAttributeStore>>createCompositeMetadata:trunkState=" + trunkState);                      
        }        
      
        ArrayList entries = new ArrayList();
        ArrayList addedAttrs = modAttrSession.getAddedAttributes();
        ArrayList modifiedAttrs = modAttrSession.getModifiedAttributes();
        ArrayList deletedAttrs = modAttrSession.getDeletedAttributes();
        //printAttrList("ADDED", addedAttrs);
        //printAttrList("MODIFIED", modifiedAttrs);
        //printAttrList("DELETED", deletedAttrs);
       
        addToEntries(modAttrSession, entries,
                SessionAttributeMetadata.Operation.ADD, addedAttrs);
        addToEntries(modAttrSession, entries,
                SessionAttributeMetadata.Operation.UPDATE, modifiedAttrs);
        entries = addToEntries(modAttrSession, entries,
                SessionAttributeMetadata.Operation.DELETE, deletedAttrs);

        CompositeMetadata result
            = new CompositeMetadata(modAttrSession.getVersion(),
                modAttrSession.getLastAccessedTimeInternal(),
                modAttrSession.getMaxInactiveInterval(),
                entries,
                trunkState,
                modAttrSession.getSsoId()); //ssoId is the extraParam here
        return result;
    }
   
    private void printAttrList(String attrListType, ArrayList attrList) {
        if (_logger.isLoggable(Level.FINER)) {
            _logger.finer("AttributeType = " + attrListType);
            String nextAttrName = null;
            for(int i=0; i<attrList.size(); i++) {
                nextAttrName = (String)attrList.get(i);
                _logger.finer("attribute[" + i + "]=" + nextAttrName);
            }
        }
    }
   
    private ArrayList addToEntries(ModifiedAttributeHASession modAttrSession,
            ArrayList entries, SessionAttributeMetadata.Operation op, ArrayList attrList) {
        String nextAttrName = null;
        Object nextAttrValue = null;
        byte[] nextValue = null;
        for(int i=0; i<attrList.size(); i++) {
            nextAttrName = (String)attrList.get(i);
            nextAttrValue = ((StandardSession) modAttrSession).getAttribute(nextAttrName);
            nextValue = null;
            try {
                nextValue = getByteArray(nextAttrValue);
            } catch (IOException ex) {}
            SessionAttributeMetadata nextAttrMetadata
                = new SessionAttributeMetadata(nextAttrName, op, nextValue);
            entries.add(nextAttrMetadata);
        }
        return entries;
    }
   
    /**
    * Create an byte[] for the session that we can then pass to
    * the HA Store.
    *
    * @param attributeValue
    *   The attribute value we are serializing
    *
    */
    protected byte[] getByteArray(Object attributeValue)
      throws IOException {
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;

        IOUtilsCaller utilsCaller = null;
        byte[] obs;
        try {
            bos = new ByteArrayOutputStream();
            //HERCULES FIXME - for now reverting back
            //need to re-examine EJBUtils and related serialization classes
            //Bug 4832603 : EJB Reference Failover
            /*  was this
            oos = new ObjectOutputStream(new BufferedOutputStream(bos));
             end was this */
              //oos = EJBUtils.getOutputStream(new BufferedOutputStream(bos), true); 
            //end - Bug 4832603
           
            if( (utilsCaller = this.getWebUtilsCaller()) != null) {
                try {
                    oos = utilsCaller.createObjectOutputStream(new BufferedOutputStream(bos), true);
                } catch (Exception ex) {}
            }
            //use normal ObjectOutputStream if there is a failure during stream creation
            if(oos == null) {
                oos = new ObjectOutputStream(new BufferedOutputStream(bos));
            }           
            oos.writeObject(attributeValue);
            oos.close();
            oos = null;

            obs = bos.toByteArray();
        }
        finally {
            if ( oos != null )  {
                oos.close();
            }
        }

        return obs;
    }
   
    /**
    * Given a byte[] containing session data, return a session
    * object
    *
    * @param state
    *   The byte[] with the session attribute data
    *
    * @return
    *   A newly created object for the given session attribute data
    */
    protected Object getAttributeValue(byte[] state)
        throws IOException, ClassNotFoundException
    {
        Object attributeValue = null;
        BufferedInputStream bis = null;
        ByteArrayInputStream bais = null;
        Loader loader = null;   
        ClassLoader classLoader = null;
        ObjectInputStream ois = null;
        Container container = manager.getContainer();
        IOUtilsCaller utilsCaller = null;
           
        try
        {
            bais = new ByteArrayInputStream(state);
            bis = new BufferedInputStream(bais);
           
            if (container != null) {
                loader = container.getLoader();
            }

            if (loader != null) {
                classLoader = loader.getClassLoader();
            }
           
            //Bug 4832603 : EJB Reference Failover
            //HERCULES FIXME: for now reverting back
            //need to look at new EJBUtils and related serialization code
            /*
          if (classLoader != null) {
            ois = new CustomObjectInputStream(bis, classLoader);
          }
          else {
            ois = new ObjectInputStream(bis);
          }
         
            //ois = EJBUtils.getInputStream(bis, classLoader, true, true);
            //end - Bug 4832603 
             */         
            if (classLoader != null) {
                if( (utilsCaller = this.getWebUtilsCaller()) != null) {
                    try {
                        ois = utilsCaller.createObjectInputStream(bis, true, classLoader);
                    } catch (Exception ex) {}
                }
            }
            if (ois == null) {
                ois = new ObjectInputStream(bis);
            }
           
            if(ois != null) {
                try {
                    attributeValue = ois.readObject();
                }
                finally {
                    if (ois != null) {
                        try {
                            ois.close();
                            bis = null;
                        }
                        catch (IOException e) {
                        }
                    }
                }
            }
        }
        catch(ClassNotFoundException e)
        {
            // FIXME Evaluate logging level for exception.
            if (_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "ClassNotFoundException occurred in getAttributeValue", e);
            }
            throw e;
        }
        catch(IOException e)
        {
            //System.err.println("getAttributeValue IOException :"+e.getMessage());
            throw e;
        }     

        return attributeValue;
    }
   
    //new serialization code for Collection
    /**
    * Create an byte[] for the session that we can then pass to
    * the HA Store.
    *
    * @param entries
    *   The Collection of entries we are serializing
    *
    */
    protected byte[] getByteArrayFromCollection(Collection entries)
      throws IOException {
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;

        IOUtilsCaller utilsCaller = null;
        byte[] obs;
        try {
            bos = new ByteArrayOutputStream();
            //HERCULES FIXME - for now reverting back
            //need to re-examine EJBUtils and related serialization classes
            //Bug 4832603 : EJB Reference Failover
            /*  was this
            oos = new ObjectOutputStream(new BufferedOutputStream(bos));
             end was this */
              //oos = EJBUtils.getOutputStream(new BufferedOutputStream(bos), true); 
            //end - Bug 4832603
           
            if( (utilsCaller = this.getWebUtilsCaller()) != null) {
                try {
                    oos = utilsCaller.createObjectOutputStream(new BufferedOutputStream(bos), true);
                } catch (Exception ex) {}
            }
            //use normal ObjectOutputStream if there is a failure during stream creation
            if(oos == null) {
                oos = new ObjectOutputStream(new BufferedOutputStream(bos));
            }
            //first write out the entriesSize
            int entriesSize = entries.size();
            oos.writeObject(Integer.valueOf(entriesSize));
            //then write out the entries
            Iterator it = entries.iterator();
            while(it.hasNext()) {
                oos.writeObject(it.next());
            }
            oos.close();
            oos = null;

            obs = bos.toByteArray();
        }
        finally {
            if ( oos != null )  {
                oos.close();
            }
        }

        return obs;
    }
   
    /**
    * Given a byte[] containing session data, return a session
    * object
    *
    * @param state
    *   The byte[] with the session attribute data
    *
    * @return
    *   A newly created object for the given session attribute data
    */
    protected Object getAttributeValueCollection(byte[] state)
        throws IOException, ClassNotFoundException
    {
        Collection attributeValueList = new ArrayList();
        Object attributeValue = null;
        BufferedInputStream bis = null;
        ByteArrayInputStream bais = null;
        Loader loader = null;   
        ClassLoader classLoader = null;
        ObjectInputStream ois = null;
        Container container = manager.getContainer();
        IOUtilsCaller utilsCaller = null;
           
        try
        {
            bais = new ByteArrayInputStream(state);
            bis = new BufferedInputStream(bais);
           
            if (container != null) {
                loader = container.getLoader();
            }

            if (loader != null) {
                classLoader = loader.getClassLoader();
            }
           
            //Bug 4832603 : EJB Reference Failover
            //HERCULES FIXME: for now reverting back
            //need to look at new EJBUtils and related serialization code
            /*
          if (classLoader != null) {
            ois = new CustomObjectInputStream(bis, classLoader);
          }
          else {
            ois = new ObjectInputStream(bis);
          }
         
            //ois = EJBUtils.getInputStream(bis, classLoader, true, true);
            //end - Bug 4832603 
             */         
            if (classLoader != null) {
                if( (utilsCaller = this.getWebUtilsCaller()) != null) {
                    try {
                        ois = utilsCaller.createObjectInputStream(bis, true, classLoader);
                    } catch (Exception ex) {}
                }
            }
            if (ois == null) {
                ois = new ObjectInputStream(bis);
            }
            if(ois != null) {
                try {
                    //first get List size
                    Object whatIsIt = ois.readObject();
                    int entriesSize = 0;
                    if(whatIsIt instanceof Integer) {
                        entriesSize = ((Integer)whatIsIt).intValue();
                    }
                    //int entriesSize = ((Integer) ois.readObject()).intValue();
                    //attributeValueList = new ArrayList(entriesSize);
                    //if (_logger.isLoggable(Level.FINE)) {
                    //    _logger.fine("first obj: " + whatIsIt + " entriesSize=" + entriesSize);
                    //}
                    for (int i = 0; i < entriesSize; i++) {
                        Object nextAttributeValue = ois.readObject();
                        attributeValueList.add(nextAttributeValue);
                    }
                }
                finally {
                    if (ois != null) {
                        try {
                            ois.close();
                            bis = null;
                        }
                        catch (IOException e) {
                        }
                    }
                }
            }
        }
        catch(ClassNotFoundException e)
        {
            // FIXME Evaluate logging level for exception.
            if (_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "ClassNotFoundException occurred in getAttributeValueCollection", e);
            }
            throw e;
        }
        catch(IOException e)
        {
            //System.err.println("getAttributeValue IOException :"+e.getMessage());
            throw e;
        }     

        return attributeValueList;
    }   
   
    //end new serialization code for Collection

    /**
    * Given a session, load its attributes
    *
    * @param modifiedAttributeSession
    *   The session (header info only) having its attributes loaded
    *
    * @param attributeList
    *   The List<AttributeMetadata> list of loaded attributes
    *
    * @return
    *   A newly created object for the given session attribute data
    */   
    protected void loadAttributes(ModifiedAttributeHASession modifiedAttributeSession,
            Collection attributeList) {
        if(_logger.isLoggable(Level.FINEST)) {
            _logger.finest("in loadAttributes -- ReplicationAttributeStore : session id=" + modifiedAttributeSession.getIdInternal());
        }

        String thisAttrName = null;
        SessionAttributeMetadata.Operation thisAttrOp = null;
        Object thisAttrVal = null;
        Iterator it = attributeList.iterator();
        while (it.hasNext()) {
            SessionAttributeMetadata nextAttrMetadata = (SessionAttributeMetadata)it.next();
            thisAttrName = nextAttrMetadata.getAttributeName();
            thisAttrOp = nextAttrMetadata.getOperation();
            byte[] nextAttrState = nextAttrMetadata.getState();
            thisAttrVal = null;
            try {
                thisAttrVal = getAttributeValue(nextAttrState);
            } catch (ClassNotFoundException ex1) {
                //FIXME log?
            } catch (IOException ex2) {}
            if(_logger.isLoggable(Level.FINEST)) {
                _logger.finest("Attr retrieved======" + thisAttrName);
            }

            if(thisAttrVal != null) { //start if
                if(_logger.isLoggable(Level.FINEST)) {
                    _logger.finest("Setting Attribute: " + thisAttrName);
                }
                modifiedAttributeSession.setAttribute(thisAttrName, thisAttrVal);
                modifiedAttributeSession.setAttributeStatePersistent(thisAttrName, false);
                modifiedAttributeSession.setAttributeStateDirty(thisAttrName, false);
            } //end if
        } //end while
    }
   

    /**
    * create a ReplicationState representing compositeMetadata
    *
    * @param id
    *   The session id
    *
    * @param compositeMetadata
    *   The CompositeMetadata
    *
    * @return
    *   A newly created ReplicationState object for the given compositeMetadata
    */
    private ReplicationState createReplicationStateFrom(String id, CompositeMetadata compositeMetadata, String command) {
        Object containerExtraParams
            //FIXED: Was   = compositeMetadata.getContainerExtraParam();
            = compositeMetadata.getExtraParam();
        byte[] containerExtraParamState = null;
        if(containerExtraParams != null) {
            try {
                containerExtraParamState
                    = getByteArray(containerExtraParams);
            } catch (IOException ex) {
                ;   //deliberate no-op
            }
        }
        String extraParamString
            = ReplicationState.extractExtraParamStringFrom(MODE_WEB, containerExtraParams);
       
        ReplicationState result
            = new ReplicationState(MODE_WEB,    //mode
                id,                             //id
                this.getApplicationId(),        //appid
                compositeMetadata.getVersion(), //version
                compositeMetadata.getLastAccessTime(), //lastAccess
                compositeMetadata.getMaxInactiveInterval(), //maxInactive
                //compositeMetadata.getExtraParam(), //extraParam
                extraParamString,   //extraParam
                null,                               //queryResult
                null,                               //instanceName
                command,                               //command
                this.serializeStatesCollection(compositeMetadata.getEntries()), //data
                compositeMetadata.getState(),          //trunkData
                containerExtraParamState);          //containerExtraParamsData
        return result;
    }
   
    private byte[] serializeStatesCollection(Collection entries) {
        byte[] result = null;
        try {
            result = getByteArrayFromCollection(entries);
        } catch (IOException ex) {}
        return result;
    }
   
    private byte[] serializeStatesCollectionPrevious(Collection entries) {
        byte[] result = null;
        try {
            result = getByteArray(entries);
        } catch (IOException ex) {}
        return result;
    }   
   
    /**
    * create a CompositeMetadata representing ReplicationState state
    *
    * @param state
    *   The ReplicationState
    *
    * @return
    *   A newly created CompositeMetadata object for the given state
    */
    private CompositeMetadata createCompositeMetadataFrom(ReplicationState state) {
        Collection entries = this.deserializeStatesCollection(state.getState());
        CompositeMetadata result
            = new CompositeMetadata(
                state.getVersion()//version
                state.getLastAccess(), //lastAccess
                state.getMaxInactiveInterval(), //maxInactive
                entries,                        //entries
                state.getTrunkState(),          //trunkState
                state.getExtraParam());     //extraParam     
        return result;
    }
   
    private Collection deserializeStatesCollection(byte[] entriesState) {
        Collection result = new ArrayList();
        try {
            result = (Collection)getAttributeValueCollection(entriesState);
        } catch (ClassNotFoundException ex1) {
            // FIXME log?
        } catch (IOException ex2) {}       
        return result;
    }
   
    private Collection deserializeStatesCollectionPrevious(byte[] entriesState) {
        Collection result = new ArrayList();
        try {
            result = (Collection)getAttributeValue(entriesState);
        } catch (ClassNotFoundException ex1) {
              // FIXME log?
        } catch (IOException ex2) {}       
        return result;
    }    
   
}
TOP

Related Classes of com.sun.enterprise.ee.web.sessmgmt.ReplicationAttributeStore

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.