001: /**
002: * High Availability Service (HA) for JOnAS
003: *
004: * Copyright (C) 2006 Distributed Systems Lab.
005: * Universidad Polit??cnica de Madrid (Spain)
006: * Contact: http://lsd.ls.fi.upm.es/lsd
007: *
008: * This library is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU Lesser General Public
010: * License as published by the Free Software Foundation; either
011: * version 2.1 of the License, or any later version.
012: *
013: * This library is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * Lesser General Public License for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public
019: * License along with this library; if not, write to the Free Software
020: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
021: * USA
022: *
023: * --------------------------------------------------------------------------
024: * $Id: StatefulBeanRefImpl.java 9684 2006-10-06 12:23:28Z benoitf $
025: * --------------------------------------------------------------------------
026: */package org.objectweb.jonas.ha;
027:
028: import java.io.ByteArrayInputStream;
029: import java.io.ByteArrayOutputStream;
030: import java.lang.reflect.Field;
031: import java.lang.reflect.Method;
032: import java.lang.reflect.Modifier;
033:
034: import javax.ejb.SessionBean;
035:
036: import org.objectweb.carol.cmi.configuration.TraceCmi;
037: import org.objectweb.carol.cmi.ha.StatefulBeanReference;
038: import org.objectweb.jonas_ejb.container.JRepStatefulInputStream;
039: import org.objectweb.jonas_ejb.container.JRepStatefulOutputStream;
040: import org.objectweb.jonas_ejb.container.JStatefulContext;
041: import org.objectweb.jonas_ejb.container.JStatefulSwitch;
042: import org.objectweb.jonas_ejb.deployment.api.SessionStatefulDesc;
043:
044: /**
045: * This class implements reference to beans
046: * @author Francisco Perez-Sorrosal (fpsorrosal@no-spam@fi.upm.es)
047: * @author Alberto Paz-Jimenez (apaz@no-spam@fi.upm.es)
048: */
049: public class StatefulBeanRefImpl implements StatefulBeanReference {
050:
051: private JStatefulSwitch bs;
052:
053: public StatefulBeanRefImpl(JStatefulSwitch bs) {
054: this .bs = bs;
055: }
056:
057: public byte[] getState() {
058: return getStatefulState(bs);
059: }
060:
061: public boolean isModified() {
062: SessionStatefulDesc ssd = (SessionStatefulDesc) bs
063: .getBeanFactory().getDeploymentDescriptor();
064: if (ssd.hasIsModifiedMethod()) {
065: Method isModifiedMethod = ssd.getIsModifiedMethod();
066: try {
067: SessionBean sb = ((JStatefulSwitch) bs)
068: .getStatefulContext().getInstance();
069: return ((Boolean) isModifiedMethod.invoke(sb,
070: (Object[]) null)).booleanValue();
071: } catch (Exception e) {
072: e.printStackTrace();
073: return true;
074: }
075: } else {
076: return true;
077: }
078: }
079:
080: /* (non-Javadoc)
081: * @see org.objectweb.carol.cmi.ha.BeanReference#injectState(byte[])
082: */
083: public void injectState(byte[] state) {
084: if (bs != null) {
085: injectState(bs, state);
086: }
087: }
088:
089: /**
090: * Extracts the state of the stateful session bean
091: * @param jss the related switch of the stateful session bean to access the
092: * SFBS's real instance
093: */
094: static private byte[] getStatefulState(JStatefulSwitch jss) {
095: ByteArrayOutputStream bos = new ByteArrayOutputStream();
096: JStatefulContext ctx = jss.getStatefulContext();
097: try {
098: SessionBean instance = ctx.getInstance();
099: JRepStatefulOutputStream out = new JRepStatefulOutputStream(
100: bos);
101: out.writeObject(instance);
102: out.close();
103: } catch (Exception e) {
104: TraceCmi.error("Can't get state of "
105: + jss.getBeanFactory().getEJBName() + "inst.");
106: }
107: return bos.toByteArray();
108: }
109:
110: /**
111: * Injects the serialized state of the bean in the corresponding beanSwitch
112: * @param bean target bean
113: * @param beanState state to inject
114: */
115: static private void injectState(JStatefulSwitch bean,
116: byte[] beanState) {
117:
118: JStatefulContext bctx = (JStatefulContext) bean
119: .getStatefulContext();
120: try {
121: ByteArrayInputStream bais = new ByteArrayInputStream(
122: beanState);
123: JRepStatefulInputStream in = new JRepStatefulInputStream(
124: bais, bean);
125: Object obj = in.readObject();
126: //if (TraceCmi.isDebugCmiHA())
127: // TraceCmi.debugCmiHA("\tDeserialized object:" + obj);
128: in.close();
129: SessionBean sb = (SessionBean) obj;
130:
131: // Deal with transient values
132: SessionBean oldInstance = bctx.getInstance();
133: Field[] fields = sb.getClass().getDeclaredFields();
134: for (int i = 0; i < fields.length; i++) {
135: if (Modifier.isTransient(fields[i].getModifiers())) {
136: try {
137: fields[i].setAccessible(true);
138: fields[i].set(sb, fields[i].get(oldInstance));
139: } catch (IllegalAccessException iae) {
140: iae.printStackTrace();
141: } catch (SecurityException se) {
142: se.printStackTrace();
143: }
144: }
145: }
146:
147: bctx.setInstance(sb);
148: sb.ejbActivate();
149: } catch (Exception e) {
150: e.printStackTrace();
151: }
152: }
153: }
|