/* * Copyright 2013, WebGate Consulting AG * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.openntf.xpt.agents; import java.security.AccessControlContext; import java.security.AccessController; import java.security.PrivilegedExceptionAction; import java.util.HashMap; import java.util.Map; import java.util.UUID; import java.util.logging.Logger; import javax.faces.context.FacesContext; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.openntf.xpt.agents.annotations.ExecutionMode; import org.openntf.xpt.core.utils.logging.LoggerFactory; import com.ibm.commons.Platform; import com.ibm.domino.xsp.module.nsf.ModuleClassLoader; import com.ibm.domino.xsp.module.nsf.NSFComponentModule; import com.ibm.domino.xsp.module.nsf.NotesContext; import com.ibm.domino.xsp.module.nsf.SessionCloner; import com.ibm.domino.xsp.module.nsf.platform.NotesPlatform; import lotus.domino.Database; import lotus.domino.Session; public abstract class XPageAgentJob extends Job implements IXPageAgent { private ExecutionMode m_ExecMode; private String m_DatabasePath; private FacesContext m_FacesContext; public FacesContext getFacesContext() { return m_FacesContext; } private int m_TaskCompletion; private AgentTaskStatus m_AgentTaskStatus = AgentTaskStatus.SCHEDULED; private String m_CurrentTaskStatus; private NSFComponentModule m_Module; private SessionCloner m_Cloner; private HashMap<String, String> m_ExecutionProperties; private Map<String, Object> m_ExtendedExecutionProperties; private final String m_JobID = UUID.randomUUID().toString(); private Logger m_Logger = LoggerFactory.getLogger(this.getClass().getCanonicalName()); public XPageAgentJob(String name) { super(name); } public ExecutionMode getExecMode() { return m_ExecMode; } public void setExecMode(ExecutionMode execMode) { m_ExecMode = execMode; } public String getDatabasePath() { return m_DatabasePath; } public void setDatabasePath(String databasePath) { m_DatabasePath = databasePath; } public Logger getLogger() { return m_Logger; } public void setLogger(Logger logger) { m_Logger = logger; } public String getJobID() { return m_JobID; } public int getTaskCompletion() { return m_TaskCompletion; } public void setTaskCompletion(int taskCompletion) { m_TaskCompletion = taskCompletion; } public String getCurrentTaskStatus() { return m_CurrentTaskStatus; } public void setCurrentTaskStatus(String currentTaskStatus) { m_CurrentTaskStatus = currentTaskStatus; } public void initCode(NSFComponentModule modCurrent, SessionCloner sesCloner, FacesContext fc) { m_Module = modCurrent; m_Cloner = sesCloner; m_FacesContext = fc; } public HashMap<String, String> getExecutionProperties() { return m_ExecutionProperties; } public void setExecutionProperties(HashMap<String, String> executionProperties) { m_ExecutionProperties = executionProperties; } public Map<String, Object> getExtendedExecutionProperties() { return m_ExtendedExecutionProperties; } public void setExtendedExecutionProperties(Map<String, Object> extendedExecutionProperties) { this.m_ExtendedExecutionProperties = extendedExecutionProperties; } public AgentTaskStatus getAgentTaskStatus() { return m_AgentTaskStatus; } public void setAgentTaskStatus(AgentTaskStatus agentTaskStatus) { m_AgentTaskStatus = agentTaskStatus; } @Override protected IStatus run(IProgressMonitor arg0) { try { return executeJob(); } catch (Exception e) { e.printStackTrace(); } return Status.CANCEL_STATUS; } private IStatus executeJob() { NotesContext context = null; Session sesCurrent = null; NotesPlatform nPlatform = null; ClassLoader currentClassLoader = null; try { NotesContext contextCheck = NotesContext.getCurrentUnchecked(); if (contextCheck != null) { throw new IllegalStateException(); } if (m_Module.isDestroyed()) { throw new IllegalStateException(); } m_Module.updateLastModuleAccess(); context = new NotesContext(m_Module); NotesContext.initThread(context); sesCurrent = m_Cloner.getSession(); Platform platform = Platform.getInstance(); nPlatform = (platform instanceof NotesPlatform) ? (NotesPlatform) platform : null; if (nPlatform != null) { nPlatform.openingXPagesViewPart(); nPlatform.addXPagesSecurityManager(); } m_Logger.info("Execute Code"); m_Logger.info("Session EffectiveUser: " + sesCurrent.getEffectiveUserName()); setAgentTaskStatus(AgentTaskStatus.RUNNING); // SWITCHING the ClassLoader currentClassLoader = (ClassLoader) AccessController.doPrivileged(new PrivilegedExceptionAction<ClassLoader>() { public ClassLoader run() throws Exception { ClassLoader rcCL = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(m_Module.getModuleClassLoader()); return rcCL; } }); AccessControlContext currentACLContext = null; if (System.getSecurityManager() != null) { currentACLContext = ((ModuleClassLoader) m_Module.getModuleClassLoader()).getAccessControlContext(); } Integer result = 0; if (currentACLContext != null) { final Session sesFin = sesCurrent; result = AccessController.doPrivileged(new PrivilegedExceptionAction<Integer>() { public Integer run() throws Exception { m_Logger.info("Running priviledged!"); Database ndbCurrent = null; String strServer = sesFin.getServerName(); if (strServer != null && m_DatabasePath != null) { ndbCurrent = sesFin.getDatabase(strServer, m_DatabasePath); } int rc = executeCode(sesFin, ndbCurrent); if (ndbCurrent != null) { ndbCurrent.recycle(); } return rc; } }, currentACLContext); } else { Database ndbCurrent = null; String strServer = sesCurrent.getServerName(); if (strServer != null && m_DatabasePath != null) { ndbCurrent = sesCurrent.getDatabase(strServer, m_DatabasePath); } result = executeCode(sesCurrent, ndbCurrent); if (ndbCurrent != null) { ndbCurrent.recycle(); } } if (getAgentTaskStatus() == AgentTaskStatus.RUNNING) { setAgentTaskStatus(AgentTaskStatus.FINISHED); } m_Logger.info("Execute Code -> DONE with code: " + result); // Thread.sleep(5000); } catch (Exception e) { setAgentTaskStatus(AgentTaskStatus.FINISHED_WITH_ERROR); e.printStackTrace(); } finally { try { if (m_Cloner != null) { m_Cloner.recycle(); m_Logger.info("m_Cloner.recycle()"); } if (currentClassLoader != null) { final ClassLoader cFin = currentClassLoader; AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { public Void run() throws Exception { Thread.currentThread().setContextClassLoader(cFin); return null; } }); } if (nPlatform != null) { nPlatform.closingXPagesViewPart(); m_Logger.info("nPlatform.closingViewPart()"); } if (context != null) { NotesContext.termThread(); m_Logger.info("NotesContext.termThread"); } if (sesCurrent != null) { sesCurrent.recycle(); m_Logger.info("Session recycled"); } m_Logger.info("XPageAgentJob Ended!"); } catch (Exception e) { e.printStackTrace(); } } return Status.OK_STATUS; } abstract public int executeCode(Session sesCurrent, Database ndbCurrent); }