/* * Copyright 2012 LinkedIn, Inc * * 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 com.linkedin.parseq.trace; import java.util.Collections; import java.util.HashMap; import java.util.Map; import com.linkedin.parseq.internal.ArgumentUtil; /** * Use this class to build new {@link ShallowTraceImp} instances. * <p> * This class is thread-safe. * * @author Chris Pettitt (cpettitt@linkedin.com) * @author Chi Chan (ckchan@linkedin.com) * @author Jaroslaw Odzga (jodzga@linkedin.com) */ public class ShallowTraceBuilder { private final Long _id; private volatile String _name; private volatile boolean _hidden; private volatile String _value; private volatile ResultType _resultType; private volatile Long _startNanos; private volatile Long _pendingNanos; private volatile Long _endNanos; private volatile boolean _systemHidden; private Map<String, String> _attributes; private volatile String _taskType; public ShallowTraceBuilder(Long id) { _id = id; } public ShallowTraceBuilder(final ShallowTrace shallowTrace) { this(shallowTrace.getId()); setResultType(shallowTrace.getResultType()); setName(shallowTrace.getName()); setValue(shallowTrace.getValue()); setStartNanos(shallowTrace.getStartNanos()); setPendingNanos(shallowTrace.getPendingNanos()); setEndNanos(shallowTrace.getEndNanos()); setHidden(shallowTrace.getHidden()); setSystemHidden(shallowTrace.getSystemHidden()); Map<String, String> attributes = shallowTrace.getAttributes(); if (!attributes.isEmpty()) { _attributes = new HashMap<String, String>(); _attributes.putAll(attributes); } setTaskType(shallowTrace.getTaskType()); } public boolean getHidden() { return _hidden; } public ShallowTraceBuilder setHidden(boolean hidden) { _hidden = hidden; return this; } public boolean getSystemHidden() { return _systemHidden; } public ShallowTraceBuilder setSystemHidden(boolean systemHidden) { _systemHidden = systemHidden; return this; } public ShallowTraceBuilder setName(final String name) { ArgumentUtil.requireNotNull(name, "name"); _name = name; return this; } public ShallowTraceBuilder setValue(final String value) { _value = value; return this; } public ShallowTraceBuilder setResultType(final ResultType resultType) { ArgumentUtil.requireNotNull(resultType, "resultType"); if (resultType != ResultType.UNFINISHED) { long nanoTime = System.nanoTime(); if (_startNanos == null) { _startNanos = nanoTime; } if (_pendingNanos == null) { _pendingNanos = nanoTime; } if (_endNanos == null) { _endNanos = nanoTime; } } _resultType = resultType; return this; } public ShallowTraceBuilder setStartNanos(Long startNanos) { _startNanos = startNanos; return this; } public ShallowTraceBuilder setPendingNanos(Long pendingNanos) { _pendingNanos = pendingNanos; return this; } public ShallowTraceBuilder setEndNanos(Long endNanos) { _endNanos = endNanos; return this; } public ShallowTraceBuilder setTaskType(String taskType) { _taskType = taskType; return this; } public Long getId() { return _id; } public String getName() { return _name; } public String getValue() { return _value; } public ResultType getResultType() { return _resultType; } public Long getStartNanos() { return _startNanos; } public Long getPendingNanos() { return _pendingNanos; } public Long getEndNanos() { return _endNanos; } public String getTaskType() { return _taskType; } public synchronized Map<String, String> getAttributes() { if (_attributes == null) { return Collections.emptyMap(); } else { return Collections.unmodifiableMap(_attributes); } } public synchronized ShallowTraceBuilder addAttribute(String key, String value) { ArgumentUtil.requireNotNull(key, "key"); ArgumentUtil.requireNotNull(value, "value"); if (_attributes == null) { _attributes = new HashMap<>(); } _attributes.put(key, value); return this; } public synchronized ShallowTraceBuilder removeAttribute(String key) { ArgumentUtil.requireNotNull(key, "key"); if (_attributes != null) { _attributes.remove(key); if (_attributes.isEmpty()) { _attributes = null; } } return this; } public ShallowTraceImp build() { /* * Order of reading volatile variable matters. * Make sure you understand it before changing the following lines. * For example it is important to read _resultType before _endNanos because * ShallowTraceImpl expects _endNanos to be set for certain types of _resultType. */ final String value = _value; final ResultType resultType = _resultType; Long endNanos = _endNanos; final Long pendingNanos = _pendingNanos; final Long startNanos = _startNanos; if (resultType == ResultType.UNFINISHED && startNanos != null && endNanos == null) { endNanos = System.nanoTime(); } return new ShallowTraceImp(_id, _name, _hidden, _systemHidden, resultType, value, startNanos, pendingNanos, endNanos, getAttributes(), _taskType); } }