/****************************************************************************** * Copyright (C) 2012 Trek Global * * Product: iDempiere ERP & CRM Smart Business Solution * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * * by the Free Software Foundation. This program is distributed in the hope * * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * * with this program; if not, write to the Free Software Foundation, Inc., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * *****************************************************************************/ package org.idempiere.broadcast; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import org.adempiere.base.event.EventManager; import org.adempiere.base.event.IEventTopics; import org.adempiere.exceptions.DBException; import org.adempiere.model.MBroadcastMessage; import org.compiere.Adempiere; import org.compiere.model.MNote; import org.compiere.model.MRole; import org.compiere.model.MUser; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.WebUtil; /** * Static methods for broadcast message service * @author Vivek * @author Deepak Pansheriya */ public class BroadcastMsgUtil { private static final CLogger logger = CLogger .getCLogger(BroadcastMsgUtil.class); // BROADCAST_MESSAGE_QUEUE /** * Publish Broadcast Message * @param messageID * @param trxName */ public static void publishBroadcastMessage(final int messageID, String trxName) { MBroadcastMessage mbMessage = new MBroadcastMessage(Env.getCtx(), messageID, trxName); String broadcastType = mbMessage.getBroadcastType(); if (MBroadcastMessage.BROADCASTTYPE_Login.equals(broadcastType) || MBroadcastMessage.BROADCASTTYPE_ImmediatePlusLogin.equals(broadcastType)) { int AD_Client_ID = Env.getAD_Client_ID(Env.getCtx()); // get list of users based on rule if (mbMessage.getTarget() != null) { String sql = "SELECT DISTINCT(AD_User_ID) FROM AD_User_Roles WHERE IsActive='Y'"; // Role if (mbMessage.getTarget().equals(MBroadcastMessage.TARGET_Role)) { sql += " AND AD_Role_ID=" + mbMessage.getAD_Role_ID(); MRole role = MRole.get(Env.getCtx(), mbMessage.getAD_Role_ID()); AD_Client_ID = role.getAD_Client_ID(); } else if (mbMessage.getTarget().equals(MBroadcastMessage.TARGET_User)) { sql += " AND AD_User_ID=" + mbMessage.getAD_User_ID(); } else if (mbMessage.getTarget().equals(MBroadcastMessage.TARGET_Client)) { sql += " AND AD_Client_ID = " + Env.getAD_Client_ID(Env.getCtx()); } // else Everybody doesn't need additional filtering int[] userIDs = DB.getIDsEx(null, sql); for (int userID : userIDs) { MUser user = MUser.get(Env.getCtx(), userID); if (! user.isActive()) continue; if (mbMessage.getTarget().equals(MBroadcastMessage.TARGET_User) || mbMessage.getTarget().equals(MBroadcastMessage.TARGET_Everybody)) { AD_Client_ID = user.getAD_Client_ID(); } MNote note = new MNote(Env.getCtx(), 0, trxName); note.setClientOrg(AD_Client_ID, 0); note.setAD_BroadcastMessage_ID(messageID); note.setAD_User_ID(userID); note.setAD_Message_ID(0); note.saveEx(); } mbMessage.setIsPublished(true); mbMessage.setProcessed(true); mbMessage.saveEx(trxName); } // create entry for users in AD_Note }else if(MBroadcastMessage.BROADCASTTYPE_Immediate.equals(broadcastType)){ mbMessage.setProcessed(true); mbMessage.setIsPublished(true); mbMessage.saveEx(trxName); } if (!MBroadcastMessage.BROADCASTTYPE_Login.equals(broadcastType)) { BroadCastMsg msg = new BroadCastMsg(); msg.setIntData(messageID); msg.setEventId(BroadCastUtil.EVENT_BROADCAST_MESSAGE); pushToQueue(msg,false); } } /** * Publish message using message service or using OSGi event service. * @param msg message to broadcast * @param isLocalOnly true to use event service, false to use message service */ public static void pushToQueue(final BroadCastMsg msg, boolean isLocalOnly) { boolean isPublished = false; if (!isLocalOnly) { msg.setSrc(WebUtil.getServerName()); isPublished = BroadCastUtil.publish(msg); } if (!isPublished) { Runnable runnable = new Runnable() { @Override public void run() { org.osgi.service.event.Event event = EventManager.newEvent( IEventTopics.BROADCAST_MESSAGE, msg, true); EventManager.getInstance().postEvent(event); } }; ScheduledThreadPoolExecutor executer = Adempiere .getThreadPoolExecutor(); executer.schedule(runnable, 0, TimeUnit.MILLISECONDS); } } /** * Broadcast Test message * @param messageID * @param AD_Session_ID */ public static void testBroadcastMessage(int messageID, int AD_Session_ID) { BroadCastMsg msg = new BroadCastMsg(); msg.setIntData(messageID); msg.setEventId(BroadCastUtil.EVENT_TEST_BROADCAST_MESSAGE); msg.setTarget(Integer.toString(AD_Session_ID)); pushToQueue(msg,true); } /** * Show all pending to acknowledge messages * @param AD_User_ID * @param messageWindow */ public static void showPendingMessage(int AD_User_ID, IBroadcastMsgPopup messageWindow) { String sql = "" + "SELECT bm.AD_BroadcastMessage_ID " + "FROM AD_Note n " + " INNER JOIN AD_BroadcastMessage bm " + " ON ( bm.AD_BroadcastMessage_ID = n.AD_BroadcastMessage_ID ) " + "WHERE n.AD_User_ID = ? " + " AND n.AD_Client_ID = ? " + " AND ( bm.BroadcastType = 'IL' OR bm.BroadcastType = 'L' ) " + " AND bm.isPublished = 'Y' " + " AND bm.IsActive = 'Y' " + " AND ( n.Processed = 'N' OR ( n.Processed = 'Y' AND bm.BroadcastFrequency = 'E' ) ) " + " AND ( bm.Expired = 'N' AND ( bm.Expiration IS NULL OR bm.Expiration > getDate() ) ) "; ArrayList mbMessages = new ArrayList(); PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = DB.prepareStatement(sql, null); pstmt.setInt(1, AD_User_ID); pstmt.setInt(2, Env.getAD_Client_ID(Env.getCtx())); rs = pstmt.executeQuery(); while (rs.next()) { mbMessages.add(MBroadcastMessage.get(Env.getCtx(), rs.getInt(1))); } } catch (Exception e) { logger.log(Level.SEVERE, "Broadcast messages could not be retrieved",e); throw new DBException(e); } finally{ DB.close(rs, pstmt); } if (mbMessages.size()>0) { messageWindow.prepareMessage(mbMessages); } } }