Package nexj.core.runtime.sys

Source Code of nexj.core.runtime.sys.SysService

// Copyright 2010 NexJ Systems Inc. This software is licensed under the terms of the Eclipse Public License 1.0
package nexj.core.runtime.sys;

import nexj.core.integration.IntegrationException;
import nexj.core.integration.MessageFormatter;
import nexj.core.integration.Sender;
import nexj.core.integration.io.ObjectOutput;
import nexj.core.meta.Metaclass;
import nexj.core.meta.Primitive;
import nexj.core.meta.integration.Channel;
import nexj.core.meta.integration.Message;
import nexj.core.meta.integration.MessageTable;
import nexj.core.meta.integration.service.Service;
import nexj.core.meta.workflow.Flow;
import nexj.core.meta.workflow.State;
import nexj.core.rpc.RPCException;
import nexj.core.rpc.TransferObject;
import nexj.core.runtime.ActionContext;
import nexj.core.runtime.Instance;
import nexj.core.runtime.SecurityViolationException;
import nexj.core.scripting.Pair;
import nexj.core.util.GUIDUtil;
import nexj.core.util.Logger;
import nexj.core.util.ObjUtil;
import nexj.core.util.StringUtil;

/**
* Messaging service implementation.
*/
public class SysService extends SysWorkflow
{
   /**
    * The class logger.
    */
   protected final static Logger s_logger = Logger.getLogger(SysService.class);
  
   /**
    * @see nexj.core.runtime.sys.SysWorkflow#getFlow(java.lang.String, int)
    */
   protected Flow getFlow(String sName, int nVersion)
   {
      return m_context.getMetadata().getService(sName, nVersion);
   }

   /**
    * @see nexj.core.runtime.sys.SysWorkflow#getFlow(java.lang.String)
    */
   protected Flow getFlow(String sName)
   {
      return m_context.getMetadata().getService(sName);
   }

   /**
    * @see nexj.core.runtime.sys.SysWorkflow#findFlow(nexj.core.meta.Metaclass, java.lang.String, java.lang.Number, nexj.core.runtime.ActionContext)
    */
   public Flow findFlow(Metaclass metaclass, String sName, Number version, ActionContext actx)
   {
      return m_context.getMetadata().findService(sName, version.intValue());
   }

   /**
    * Starts the service flow.
    */
   public Instance invoke(Metaclass metaclass, String sName, Object message, String sOutput, Pair args, ActionContext actx) throws IntegrationException
   {
      Service service = (Service)getFlow(sName);
      boolean bSecure = m_context.isSecure();

      if (bSecure && service.getPrivilege() != null &&
         !m_context.getPrivilegeSet().contains(service.getPrivilege()))
      {
         throw new SecurityViolationException("err.integration.service.unauthorized",
            new Object[]{service.getFullName()});
      }

      if (service.getInterface() != null)
      {
         MessageTable table = service.getInterface().getRequestTable();
        
         if (!(message instanceof TransferObject) ||
            table.getMessageCount() != 0 && table.findMessage(((TransferObject)message).getClassName()) == null)
         {
            throw new IntegrationException("err.integration.service.inputMessage", new Object[]{service.getFullName()});
         }
      }

      if (s_logger.isDebugEnabled())
      {
         s_logger.debug("Invoking " + service);
      }

      Instance instance = null;

      try
      {
         m_context.setSecure(false);
         instance = new Instance(metaclass, m_context);

         State state = new State(service, true);

         state.setReservedValue(0, instance);
         state.setReservedValue(1, state);
         state.setValue(Service.OUTPUT, sOutput);
         state.setToken(service, message);

         int i = 0;

         for (Pair pair = args; pair != null; pair = pair.getNext())
         {
            if (i >= service.getArgumentCount())
            {
               i = -1;
               break;
            }
           
            state.setValue(service.getArgument(i++), pair.getHead());
         }

         if (i != service.getArgumentCount())
         {
            throw new IntegrationException("err.integration.service.argCount",
               new Object[]{Primitive.createInteger(Pair.length(args)),
                  Primitive.createInteger(service.getArgumentCount())});
         }

         instance.setNew();
         instance.setValue("name", service.getName());
         instance.setValue("version", Primitive.createInteger(service.getVersion()));
         instance.setValue("oid", EMPTY_BINARY);
         instance.setValue("class", "");
         instance.setValue("local", GUIDUtil.generateGUID());
         instance.setValue("object", null);
         instance.setValue("state", state);
         instance.setValue("serializedState", null);
         instance.setValue("serializedVariables", null);
         instance.invoke("create");
         m_context.setSecure(bSecure);
         instance.invoke("run");
      }
      catch (Throwable e)
      {
         if (instance != null && instance.getState() != Instance.INIT)
         {
            m_context.setSecure(false);
            instance.invoke("delete");
         }

         ObjUtil.rethrow(e);
      }
      finally
      {
         m_context.setSecure(bSecure);
      }

      return instance;
   }

   /**
    * @see nexj.core.runtime.sys.SysWorkflow#complete(nexj.core.runtime.Instance, nexj.core.runtime.ActionContext)
    */
   public void complete(Instance instance, ActionContext actx)
   {
      State state = (State)instance.getValue("state");
      Service service = (Service)state.getFlow();
      String sChannel = (String)state.getValue(Service.OUTPUT);
      Channel channel = (StringUtil.isEmpty(sChannel)) ? null : m_context.getMetadata().getChannel(sChannel);
      Object value = state.getToken(null);

      if (s_logger.isDumpEnabled())
      {
         s_logger.dump("Output message:");
         s_logger.dump(value);
      }
     
      if (service.getInterface() != null)
      {
         MessageTable responseTable = service.getInterface().getResponseTable();
         Message message = null;

         if (responseTable.getMessageCount() != 0)
         {
            if (!(value instanceof TransferObject) ||
               (message = responseTable.findMessage(((TransferObject)value).getClassName())) == null)
            {
               throw new IntegrationException("err.integration.service.outputMessage", new Object[]{service.getFullName()});
            }

            if (message.getFormat() == null)
            {
               message = null;
            }
         }
         else if (responseTable.getFormat() != null)
         {
            channel = null;
         }

         if (channel != null && message != null)
         {
            if (channel.getSender() == null)
            {
               throw new RPCException("err.rpc.notSender", new Object[]{channel.getName()});
            }

            Sender sender = (Sender)channel.getSender().getInstance(m_context);
            ObjectOutput output = sender.createOutput();

            ((MessageFormatter)message.getFormat().getFormatter().getInstance(m_context)).format((TransferObject)value, message, output);
            TransferObject tobj = new TransferObject(1);
            tobj.setValue(Sender.BODY, output.getObject());
            value = tobj;
         }
      }

      if (channel != null)
      {
         if (!(value instanceof TransferObject))
         {
            throw new IntegrationException("err.integration.service.outputMessage", new Object[]{service.getFullName()});
         }

         m_context.getUnitOfWork().addMessage(channel, (TransferObject)value);
      }

      boolean bSecure = m_context.isSecure();
     
      try
      {
         m_context.setSecure(false);
         instance.invoke("delete");
      }
      finally
      {
         m_context.setSecure(bSecure);
      }
   }
}
TOP

Related Classes of nexj.core.runtime.sys.SysService

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.