Package org.jboss.fresh.remoteshell.ejb.impl

Source Code of org.jboss.fresh.remoteshell.ejb.impl.RemoteShellImpl

package org.jboss.fresh.remoteshell.ejb.impl;

import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.List;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import javax.transaction.UserTransaction;

import org.jboss.fresh.vfs.UserCtx;
import org.jboss.fresh.registry.RegistryContext;
import org.jboss.fresh.shell.ProcessInfo;
import org.jboss.fresh.shell.Shell;
import org.jboss.fresh.shell.ShellException;
import org.jboss.fresh.shell.ShellIOException;
import org.jboss.fresh.shell.ShellInitializationException;
import org.jboss.fresh.shell.SystemShell;

/**
* Shell session can timeout. Using a timed-out session is like having a ghost around. Even the system is not aware of it, so
* it can easily happen that resources are allocated and not released as long as remote object impl has a reference to shell impl
* The logical thing to do would be to throw an exception to notify a client of a timeout. Client can then reconnect and try to repeat the action.
* Automatic reinitalisation is very problematic since many sessions have their environment initialized at the beginning. And only client knows exactly
* what's involved.
*
* @author mare
* @version $Revision: 1.8 $
* @modified $Author: cerar $
*/
public class RemoteShellImpl implements SessionBean {
  private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(RemoteShellImpl.class);
  private static final org.apache.log4j.Logger log_cmd = org.apache.log4j.Logger.getLogger(RemoteShellImpl.class.getName() + ".commands");
  private static final org.apache.log4j.Logger log_treplacer = org.apache.log4j.Logger.getLogger(RemoteShellImpl.class.getName() + ".throwable");
  private static final String SYSTEM_SHELL_JNDI = "java:/SystemShell";
  String sessid;
  boolean interactive;
  transient Shell shell;
  UserCtx uctx;
  public static final String KEEP_EXCEPTIONS_ENV_NAME = "KEEP_EXCEPTIONS";
  private SessionContext sctx;

  public void ejbCreate() throws ShellException {
    ejbCreate(null, false, null);
  }

  public void ejbCreate(String sessid) throws ShellException {
    ejbCreate(sessid, false, null);
  }

  public void ejbCreate(boolean interactive) throws ShellException {
    ejbCreate(null, interactive, null);
  }

  public void ejbCreate(boolean interactive, Properties roProps) throws ShellException {
    ejbCreate(null, interactive, roProps);
  }

  public void ejbCreate(String sessid, boolean interactive) throws ShellException {
    ejbCreate(sessid, interactive, null);
  }

  public void ejbCreate(String sessid, boolean interactive, Properties roProps) throws ShellException {
    this.interactive = interactive;
    this.sessid = sessid;
    try {
      /*if (sctx != null) {
        TxSupport.assignUTForThread(sctx.getUserTransaction());
      }*/

      reinitShell();

      if (roProps != null) {
        Iterator it = roProps.entrySet().iterator();
        while (it.hasNext()) {
          Map.Entry ent = (Map.Entry) it.next();
          shell.setROEnvProperty((String) ent.getKey(), (String) ent.getValue());
        }
      }
    } catch (Exception ex) {
      throw new ShellInitializationException(ex);
    }/* finally {
      TxSupport.clearUTForThread();
    }*/
  }

//  public void ejbPostCreate(String sessid) {
//  }

  public void ejbRemove() {
    try {
      /*if (sctx != null) {
        TxSupport.assignUTForThread(sctx.getUserTransaction());
      }*/

      if (shell == null) {
        ejbActivate();
      }
      if (shell != null) {
        shell.close(); // means all processes
      }
      shell = null;
      sessid = null;
    } catch (Exception ex) {
      if (ex instanceof org.jboss.fresh.shell.SessionTimeoutException) {
        log.info("Shell session has timedout.");
      } else {
        log.error("Error while removing EJB!", ex);
      }
    }/* finally {
      TxSupport.clearUTForThread();
    }*/
  }

  public void setSessionContext(SessionContext ctx) {

    sctx = ctx;

    //log.debug("[RemoteShell] Session ctx set.");
    /*
    try {
       // this method never returns null
       Principal principal=ctx.getCallerPrincipal();

       InitialContext naming=new InitialContext();
       UserDirectory udir=(UserDirectory)naming.lookup("UserDirectory");
       uctx=udir.getUserCtx(principal);
    } catch(Exception ex) {
       ex.printStackTrace();
    }
    */
  }

  public void unsetSessionContext() {
    uctx = null;
  }

  public void ejbActivate() {
    //log.debug("ejbActivate called");
    try {
      if (sctx != null) {
        //TxSupport.assignUTForThread(sctx.getUserTransaction());
      }
      reinitShell();
    } catch (Exception ex) {
      if (ex instanceof org.jboss.fresh.shell.SessionTimeoutException) {
        log.info("Shell session has timedout.");
      } else {
        log.error("Error while activating EJB!", ex);
      }
    } finally {
      //TxSupport.clearUTForThread();
    }
  }

  public void ejbPassivate() {
  }

  private void reinitShell() throws NamingException, ShellException {
    if (shell == null) {
      InitialContext ctx = null;
      SystemShell sysshell;
      String sslookup = SYSTEM_SHELL_JNDI;
      try {
        ctx = new InitialContext();
        Context env = (Context) ctx.lookup("java:comp/env");
        sslookup = (String) env.lookup("SystemShellJNDI");
      } catch (NameNotFoundException ex) {
        log.info("SystemShellJNDI ENV not set. Using defaults.");
      } finally {
        if (ctx != null) {
          try {
            ctx.close();
          } catch (Exception e) {
            log.error("Could not close " + ctx + '!', e);
          }
        }
      }
      try {
        sysshell = (SystemShell) new RegistryContext().lookup(sslookup);
//      } catch(NameNotFoundException ex) {
//        ex.printStackTrace();
//        throw new RuntimeException(ex.getMessage());
      } catch (NamingException ex) {
        log.error("Error while reiniting shell!", ex);
        throw new RuntimeException(ex);
      }
      if (sessid == null) {
        shell = sysshell.startSession(uctx, interactive);
        sessid = shell.getSessionID();
      } else {
        shell = sysshell.continueSession(sessid);
      }
      if (shell == null) {
        throw new org.jboss.fresh.shell.SessionTimeoutException("Shell session has timed out.");
      }
    }
  }

  public String startNewSession() throws ShellException {
    shell = null;
    ejbActivate();
    return sessid;
  }

  public ProcessInfo execute(String cmdline) throws ShellException {
    return execute(cmdline, null);
  }

  public ProcessInfo execute(String cmdline, List input) throws ShellException {
    try {
      //TxSupport.assignUTForThread(sctx.getUserTransaction());
      reinitShell();
      log_cmd.debug(cmdline);
      return shell.execute(cmdline, input, true);
    } catch (RuntimeException e) {
      log.error("Error while executing " + cmdline + "!", e);
      throw (RuntimeException) processThrowable(e);
    } catch (org.jboss.fresh.shell.SessionTimeoutException e) {
      log.info("Session has timed out");
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw (org.jboss.fresh.shell.SessionTimeoutException) th;
      }
    } catch (ShellException e) {
      log.error("Error while executing " + cmdline + "!", e);
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw (ShellException) th;
      }
    } catch (Throwable e) {
      log.error("Error while executing " + cmdline + "!", e);
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw new ShellException(th);
      }
    } /*finally {
      TxSupport.clearUTForThread();
    }   */
  }
/*
  public String executeAsString(String cmdline) throws ShellException {
    try {
      reinitShell();
      log_cmd.debug(cmdline);
      return shell.executeAsString(cmdline, true);
    } catch (RuntimeException e) {
      log.error("Error while executing " + cmdline + "!", e);
      throw (RuntimeException) processThrowable(e);
    } catch (org.jboss.fresh.shell.SessionTimeoutException e) {
      log.info("Session has timed out");
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw (org.jboss.fresh.shell.SessionTimeoutException) th;
      }
    } catch (ShellException e) {
      log.error("Error while executing " + cmdline + "!", e);
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw (ShellException) th;
      }
    } catch (Throwable e) {
      log.error("Error while executing " + cmdline + "!", e);
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw new ShellException(th);
      }
    }
  }
*/

  public Object executeAsObject(String cmdline) throws ShellException {
    return executeAsObject(cmdline, null);
  }

  public Object executeAsObject(String cmdline, List input) throws ShellException {
    try {
      UserTransaction tx = sctx.getUserTransaction();
      //TxSupport.assignUTForThread(tx);

      reinitShell();
      log_cmd.debug(cmdline);
      return shell.executeAsObject(cmdline, input, true);
    } catch (RuntimeException e) {
      log.error("Error while executing " + cmdline + "!", e);
      throw (RuntimeException) processThrowable(e);
    } catch (org.jboss.fresh.shell.SessionTimeoutException e) {
      log.info("Session has timed out");
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw (org.jboss.fresh.shell.SessionTimeoutException) th;
      }
    } catch (ShellException e) {
      log.error("Error while executing " + cmdline + "!", e);
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw (ShellException) th;
      }
    } catch (Throwable e) {
      log.error("Error while executing " + cmdline + "!", e);
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw new ShellException(th);
      }
    }/* finally {
      TxSupport.clearUTForThread();
    }*/
  }

  public String getEnvProperty(String propname) throws ShellException {
    try {
      //TxSupport.assignUTForThread(sctx.getUserTransaction());
      reinitShell();
      return shell.getEnvProperty(propname);
    } catch (RuntimeException e) {
      log.error("Error while executing getEnvProperty(" + propname + ")", e);
      throw (RuntimeException) processThrowable(e);
    } catch (org.jboss.fresh.shell.SessionTimeoutException e) {
      log.error("Error while executing getEnvProperties(" + propname + ")", e);
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw (org.jboss.fresh.shell.SessionTimeoutException) th;
      }
    } catch (ShellException e) {
      log.error("Error while executing getEnvProperties(" + propname + ")", e);
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw (ShellException) th;
      }
    } catch (Throwable e) {
      log.error("Error while executing getEnvProperties(" + propname + ")", e);
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw new ShellException(th);
      }
    } /*finally {
      TxSupport.clearUTForThread();
    }   */
  }

  public Properties getEnvProperties() throws ShellException {
    try {
      //TxSupport.assignUTForThread(sctx.getUserTransaction());
      reinitShell();
      return shell.getEnvProperties();
    } catch (RuntimeException e) {
      log.error("Error while executing getEnvProperties()", e);
      throw (RuntimeException) processThrowable(e);
    } catch (org.jboss.fresh.shell.SessionTimeoutException e) {
      log.info("Session has timed out");
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw (org.jboss.fresh.shell.SessionTimeoutException) th;
      }
    } catch (ShellException e) {
      log.error("Error while executing getEnvProperties()", e);
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw (ShellException) th;
      }
    } catch (Throwable e) {
      log.error("Error while executing getEnvProperties()", e);
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw new ShellException(th);
      }
    } /*finally {
      TxSupport.clearUTForThread();
    }*/
  }

  public void setEnvProperty(String name, String value) throws ShellException {
    try {
      //TxSupport.assignUTForThread(sctx.getUserTransaction());
      reinitShell();
      shell.setEnvProperty(name, value);
    } catch (RuntimeException e) {
      log.error("Error while executing setEnvProperty(" + name + ", " + value + ")", e);
      throw (RuntimeException) processThrowable(e);
    } catch (org.jboss.fresh.shell.SessionTimeoutException e) {
      log.info("Session has timed out");
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw (org.jboss.fresh.shell.SessionTimeoutException) th;
      }
    } catch (ShellException e) {
      log.error("Error while executing setEnvProperty(" + name + ", " + value + ")", e);
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw (ShellException) th;
      }
    } catch (Throwable e) {
      log.error("Error while executing setEnvProperty(" + name + ", " + value + ")", e);
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw new ShellException(th);
      }
    }/* finally {
      TxSupport.clearUTForThread();
    }*/
  }

  public Object read(String id) throws IOException {
    try {
      //TxSupport.assignUTForThread(sctx.getUserTransaction());
      reinitShell();
      Object obj = shell.read(id);
      //log.debug("### obj: " + obj);
      return replaceThrowable(obj);
    } catch (RuntimeException e) {
      log.error("Error while executing read(" + id + ")", e);
      throw (RuntimeException) processThrowable(e);
    } catch (IOException e) {
      log.error("Error while executing read(" + id + ")", e);
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw (IOException) th;
      }
    } catch (Throwable e) {
      log.error("Error while executing read(" + id + ")", e);
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw new ShellIOException(th);
      }
    }/* finally {
      TxSupport.assignUTForThread(sctx.getUserTransaction());
    }*/
  }

  public LinkedList readBuffer(String id, int maxsize) throws IOException {
    try {
      //TxSupport.assignUTForThread(sctx.getUserTransaction());
      reinitShell();
      LinkedList l = shell.readBuffer(id, maxsize);
      //log.debug("### list: (" + l.size() +") "  + l);
      l = replaceThrowables(l);
      return l;
    } catch (RuntimeException e) {
      log.error("Error while executing readBuffer(" + id + ", " + maxsize + ")", e);
      throw (RuntimeException) processThrowable(e);
    } catch (IOException e) {
      log.error("Error while executing read(" + id + ")", e);
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw (IOException) th;
      }
    } catch (Throwable e) {
      log.error("Error while executing read(" + id + ")", e);
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw new ShellIOException(th);
      }
    } /*finally {
      TxSupport.clearUTForThread();
    } */
  }

  public void write(String id, Object obj) throws IOException {
    try {
      //TxSupport.assignUTForThread(sctx.getUserTransaction());
      reinitShell();
      shell.write(id, obj);
    } catch (RuntimeException e) {
      log.error("Error while executing write(" + id + ", " + obj + ")", e);
      throw (RuntimeException) processThrowable(e);
    } catch (IOException e) {
      log.error("Error while executing read(" + id + ")", e);
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw (IOException) th;
      }
    } catch (Throwable e) {
      log.error("Error while executing read(" + id + ")", e);
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw new ShellIOException(th);
      }
    }/* finally {
      TxSupport.clearUTForThread();
    }*/
  }

  public void writeBuffer(String id, LinkedList obj) throws IOException {
    try {
      //TxSupport.assignUTForThread(sctx.getUserTransaction());
      reinitShell();
      shell.writeBuffer(id, obj);
    } catch (RuntimeException e) {
      log.error("Error while executing writeBuffer(" + id + ", " + obj + ")", e);
      throw (RuntimeException) processThrowable(e);
    } catch (IOException e) {
      log.error("Error while executing read(" + id + ")", e);
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw (IOException) th;
      }
    } catch (Throwable e) {
      log.error("Error while executing read(" + id + ")", e);
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw new ShellIOException(th);
      }
    } /*finally {
      TxSupport.clearUTForThread();
    }   */
  }

  // means only the specified process
  public void close(String id, int streamid) throws IOException {
    try {
      //TxSupport.assignUTForThread(sctx.getUserTransaction());
      reinitShell();
      shell.close(id, streamid);
    } catch (RuntimeException e) {
      log.error("Error while executing stream close (processId: " + id + ", streamId: " + streamid + ")", e);
      throw (RuntimeException) processThrowable(e);
    } catch (IOException e) {
      log.error("Error while executing stream close (processId: " + id + ", streamId: " + streamid + ")", e);
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw (IOException) th;
      }
    } catch (Throwable e) {
      log.error("Error while executing stream close (processId: " + id + ", streamId: " + streamid + ")", e);
      Throwable th = processThrowable(e);
      if (th instanceof RuntimeException) {
        throw  (RuntimeException) th;
      } else {
        throw new ShellIOException(th);
      }
    } finally {
      //TxSupport.clearUTForThread();
    }
  }

  public String getSessionID() {
    return sessid;
  }

  public boolean isValid() {
    try {
      reinitShell();
      shell.using();
    } catch (Exception ex) {
      return false;
    }
    return true;
  }

  /**
   * This method is called to replace an ErrorEOF object with such that it has properly processed IOException
   * which is its payload.
   */
  private Object replaceThrowable(Object o) {
    if (o instanceof org.jboss.fresh.io.ErrorEOF) {
      o = processThrowable(((org.jboss.fresh.io.ErrorEOF) o).getIOException());
      if (!(o instanceof IOException)) {
        o = new org.jboss.fresh.shell.ShellIOException((Throwable) o);
      }
      o = new org.jboss.fresh.io.ErrorEOF((IOException) o);
    }
    return o;
  }

  /**
   * This method is called to replace each ErrorEOF object with such that it has properly processed IOException
   * which is its payload.
   */
  private LinkedList replaceThrowables(LinkedList l) {
    LinkedList l2 = new LinkedList();
    while (l.size() > 0) {
      Object o = l.removeFirst();
      if (o instanceof org.jboss.fresh.io.ErrorEOF) {
        o = processThrowable(((org.jboss.fresh.io.ErrorEOF) o).getIOException());
        if (!(o instanceof IOException)) {
          o = new org.jboss.fresh.shell.ShellIOException((Throwable) o);
        }
        o = new org.jboss.fresh.io.ErrorEOF((IOException) o);
      }
      l2.add(o);
    }
    return l2;
  }

  /**
   * This method inspects a passed throwable for any Throwables which should not be sent to the client
   * and if necessary copies the entire stack trace in terms of ThrowableProxy - an extension of RuntimeException.
   */
  private Throwable processThrowable(Throwable t) {
    Throwable torig = t;
    Throwable tnu;
    boolean needReplace = false;
    java.util.LinkedList ls = new java.util.LinkedList();
    while (t != null) {
      if (log.isDebugEnabled()) {
        log.debug("t: " + t, t);
      }
      if (!isPartOfClientAPI(t.getClass())) {
        needReplace = true;
      }
      tnu = new org.jboss.fresh.util.ThrowableProxy(t);
      ls.add(tnu);

      t = t.getCause();
    }
    t = (Throwable) ls.removeLast();
    while (ls.size() > 0) {
      tnu = (Throwable) ls.removeLast();
      if (tnu == null) {
        break;
      }
      tnu.initCause(t);
      t = tnu;
    }

    if (needReplace) {
      return t;
    }
    return torig;
  }

  private boolean isPartOfClientAPI(Class c) {
    final String className = c.getName();

    if (className.startsWith("java.")) {
      return true;
    }
    if (className.startsWith("javax.")) {
      return true;
    }
    if (className.startsWith("org.jboss.fresh.parsek.cms.")) {
      return true;
    }
    String pkg = "org.jboss.fresh.shell.";
    if (className.startsWith(pkg) && className.indexOf(".", pkg.length()) == -1) {
      return true;
    }

    // try to get the names of classes which also should not be replaced
    String nonreplacable;
    try {
      reinitShell();
      nonreplacable = shell.getEnvProperty(KEEP_EXCEPTIONS_ENV_NAME);
    } catch (Exception e) {
      log_treplacer.warn("Could not read environment variable " + KEEP_EXCEPTIONS_ENV_NAME);
      nonreplacable = "";
    }

    log_treplacer.info(KEEP_EXCEPTIONS_ENV_NAME + " = " + nonreplacable);

    if(nonreplacable == null)
        return false;
   
    final StringTokenizer st = new StringTokenizer(nonreplacable, "\r\n ;,:");
    while (st.hasMoreTokens()) {
      final String el = st.nextToken();
      if (matches(className, el)) {
        return true;
      }
    }

    return false;
  }

  private boolean matches(final String value, String search) {
    if (search == null) {
      return false;
    }

    search = search.trim();

    if ("".equals(search)) {
      return false;
    }

    final String s = search
      .replaceAll("\\.", "\\.")
      .replaceAll("\\?", ".")
      .replaceAll("\\*", ".*");

    final boolean b = value.startsWith(s)// matches(s);

    log_treplacer.debug(value + " matches " + s + "? " + b + ", orig: " + search);

    return b;

  }

}
TOP

Related Classes of org.jboss.fresh.remoteshell.ejb.impl.RemoteShellImpl

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.