001/* 002 * (C) Copyright 2013 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * vpasquier <vpasquier@nuxeo.com> 018 * slacoin <slacoin@nuxeo.com> 019 */ 020 021package org.nuxeo.ecm.automation.core.trace; 022 023import java.util.LinkedList; 024import java.util.Stack; 025 026import org.nuxeo.ecm.automation.OperationCallback; 027import org.nuxeo.ecm.automation.OperationException; 028import org.nuxeo.ecm.automation.OperationType; 029 030/** 031 * Automation Abstract tracer recording all automation execution traces. 032 * 033 * @since 5.9.1 034 */ 035public abstract class BasedTracer implements OperationCallback { 036 037 protected final TracerFactory factory; 038 039 protected final LinkedList<Call> calls = new LinkedList<Call>(); 040 041 protected Stack<Trace> callingStacks = new Stack<Trace>(); 042 043 protected Call parent; 044 045 protected OperationType chain; 046 047 protected Trace trace; 048 049 protected Boolean printable; 050 051 protected BasedTracer(TracerFactory factory, Boolean printable) { 052 this.factory = factory; 053 this.printable = printable; 054 } 055 056 protected void pushContext(OperationType newChain) { 057 if (chain != null) { 058 callingStacks.push(new Trace(parent, chain, calls)); 059 parent = calls.isEmpty() ? null : calls.getLast(); 060 calls.clear(); 061 } 062 chain = newChain; 063 } 064 065 protected void popContext() { 066 calls.clear(); 067 if (callingStacks.isEmpty()) { 068 parent = null; 069 chain = null; 070 return; 071 } 072 Trace trace = callingStacks.pop(); 073 parent = trace.parent; 074 chain = trace.chain; 075 calls.addAll(trace.operations); 076 } 077 078 protected void saveTrace(Trace popped) { 079 if (parent == null) { 080 trace = popped; 081 chain = null; 082 calls.clear(); 083 factory.onTrace(popped); 084 } else { 085 parent.nested.add(popped); 086 popContext(); 087 } 088 } 089 090 @Override 091 public void onChain(OperationType chain) { 092 pushContext(chain); 093 } 094 095 @Override 096 public void onOutput(Object output) { 097 saveTrace(new Trace(parent, chain, calls, output)); 098 } 099 100 @Override 101 public void onError(OperationException error) { 102 saveTrace(new Trace(parent, chain, calls, error)); 103 } 104 105 @Override 106 public Trace getTrace() { 107 return trace; 108 } 109 110 @Override 111 public String getFormattedText() { 112 return printable ? trace.getFormattedText() : ""; 113 } 114}