001/* 002// This software is subject to the terms of the Eclipse Public License v1.0 003// Agreement, available at the following URL: 004// http://www.eclipse.org/legal/epl-v10.html. 005// You must accept the terms of that agreement to use this software. 006// 007// Copyright (C) 2011-2013 Pentaho 008// All Rights Reserved. 009*/ 010package mondrian.server; 011 012import mondrian.olap.MondrianServer; 013import mondrian.rolap.RolapConnection; 014import mondrian.util.ArrayStack; 015 016/** 017 * Point of execution from which a service is invoked. 018 */ 019public class Locus { 020 public final Execution execution; 021 public final String message; 022 public final String component; 023 024 private static final ThreadLocal<ArrayStack<Locus>> THREAD_LOCAL = 025 new ThreadLocal<ArrayStack<Locus>>() { 026 protected ArrayStack<Locus> initialValue() { 027 return new ArrayStack<Locus>(); 028 } 029 }; 030 031 /** 032 * Creates a Locus. 033 * 034 * @param execution Execution context 035 * @param component Description of a the component executing the query, 036 * generally a method name, e.g. "SqlTupleReader.readTuples" 037 * @param message Description of the purpose of this statement, to be 038 * printed if there is an error 039 */ 040 public Locus( 041 Execution execution, 042 String component, 043 String message) 044 { 045 assert execution != null; 046 this.execution = execution; 047 this.component = component; 048 this.message = message; 049 } 050 051 public static void pop(Locus locus) { 052 final Locus pop = THREAD_LOCAL.get().pop(); 053 assert locus == pop; 054 } 055 056 public static void push(Locus locus) { 057 THREAD_LOCAL.get().push(locus); 058 } 059 060 public static Locus peek() { 061 return THREAD_LOCAL.get().peek(); 062 } 063 064 public static <T> T execute( 065 RolapConnection connection, 066 String component, 067 Action<T> action) 068 { 069 final Statement statement = connection.getInternalStatement(); 070 final Execution execution = new Execution(statement, 0); 071 return execute(execution, component, action); 072 } 073 074 public static <T> T execute( 075 Execution execution, 076 String component, 077 Action<T> action) 078 { 079 final Locus locus = 080 new Locus( 081 execution, 082 component, 083 null); 084 Locus.push(locus); 085 try { 086 return action.execute(); 087 } finally { 088 Locus.pop(locus); 089 } 090 } 091 092 public final MondrianServer getServer() { 093 return execution.statement.getMondrianConnection().getServer(); 094 } 095 096 public interface Action<T> { 097 T execute(); 098 } 099} 100 101// End Locus.java