blob: c4cd59ffbcaf5bd5a58b7daf83541c463195c22a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2015 Xored Software Inc and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Xored Software Inc - initial API and implementation and/or initial documentation
*******************************************************************************/
package org.eclipse.rcptt.reporting.core;
import java.util.Map;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.common.util.EMap;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.rcptt.ecl.core.BoxedValue;
import org.eclipse.rcptt.ecl.core.ProcessStatus;
import org.eclipse.rcptt.ecl.internal.core.ProcessStatusConverter;
import org.eclipse.rcptt.ecl.runtime.BoxedValues;
import org.eclipse.rcptt.reporting.Q7Info;
import org.eclipse.rcptt.reporting.ReportingFactory;
import org.eclipse.rcptt.sherlock.core.INodeBuilder;
import org.eclipse.rcptt.sherlock.core.model.sherlock.report.LoggingCategory;
import org.eclipse.rcptt.sherlock.core.model.sherlock.report.LoggingData;
import org.eclipse.rcptt.sherlock.core.model.sherlock.report.Node;
import org.eclipse.rcptt.sherlock.core.model.sherlock.report.ReportFactory;
import org.eclipse.rcptt.sherlock.core.model.sherlock.report.Snaphot;
import org.eclipse.rcptt.sherlock.core.reporting.EventProviderManager;
import org.eclipse.rcptt.sherlock.core.reporting.Procedure1;
import org.eclipse.rcptt.tesla.core.Q7WaitUtils;
import org.eclipse.rcptt.tesla.core.info.InfoFactory;
import org.eclipse.rcptt.tesla.core.info.Q7WaitInfoRoot;
public class ReportHelper {
public static Q7Info getInfo(Node node) {
synchronized (node) {
Q7Info value = getInfoOnly(node);
if (value == null) {
value = ReportingFactory.eINSTANCE.createQ7Info();
node.getProperties().put(IQ7ReportConstants.ROOT, value);
}
return (Q7Info) value;
}
}
public static void setInfo(INodeBuilder node, Q7Info info) {
assert info.getType() != null;
assert info.getResult() == null;
node.setProperty(IQ7ReportConstants.ROOT, info);
}
{
// Prevents class loader lock in synchronized context. See http://jira4.xored.com/browse/QS-3201#comment-22683
InfoFactory.eINSTANCE.createQ7WaitInfoRoot();
}
public static Q7WaitInfoRoot getWaitInfo(Node node, boolean create) {
synchronized (node) {
Q7WaitInfoRoot value = (Q7WaitInfoRoot) node.getProperties().get(
IQ7ReportConstants.ROOT_WAIT);
if (value != null) {
return (Q7WaitInfoRoot) value;
}
if (value == null && create) {
value = InfoFactory.eINSTANCE.createQ7WaitInfoRoot();
value.setStartTime(System.currentTimeMillis());
node.getProperties().put(IQ7ReportConstants.ROOT_WAIT, value);
}
return (Q7WaitInfoRoot) value;
}
}
public static void putProperties(INodeBuilder node, Map<String, ? extends EObject> properties) {
for (Map.Entry<String, ? extends EObject> entry : properties.entrySet()) {
node.setProperty(entry.getKey(), entry.getValue());
}
}
public static void appendLog(Node node, LoggingCategory category, String log) {
String logKey = getLogCategoryKey(category);
EMap<String, EObject> properties = node.getProperties();
LoggingData data = (LoggingData) properties.get(logKey);
if (data == null)
properties.put(logKey, data = ReportFactory.eINSTANCE.createLoggingData());
StringBuilder sb = new StringBuilder(data.getText());
sb.append(log);
sb.append("\n");
data.setText(sb.toString());
}
private static String getLogCategoryKey(LoggingCategory category) {
return "log_" + category.name();
}
public static Q7Info getInfoOnly(Node node) {
synchronized (node) {
EObject value = node.getProperties().get(IQ7ReportConstants.ROOT);
if (value instanceof Q7Info) {
return (Q7Info) value;
}
return null;
}
}
public static Q7Info createInfo() {
return ReportingFactory.eINSTANCE.createQ7Info();
}
public static void startWaitInfo(INodeBuilder node, final String kind, final String className) {
Q7WaitUtils.startInfo(kind, className, getWaitInfo(node));
}
public static void finishWaitInfo(INodeBuilder node, final String kind, final String className) {
Q7WaitUtils.finishInfo(kind, className, getWaitInfo(node));
}
public static void updateWaitInfo(INodeBuilder node, final String kind, final String className) {
Q7WaitUtils.updateInfo(kind, className, getWaitInfo(node));
}
/** Leaks Q7WaitInfoRoot reference in unsynchronized context */
public static Q7WaitInfoRoot getWaitInfo(INodeBuilder node) {
final Q7WaitInfoRoot waitInfo[] = new Q7WaitInfoRoot[1];
node.update(new Procedure1<Node>() {
@Override
public void apply(Node node) {
// Leaking reference to unsynchronized context
waitInfo[0] = getWaitInfo(node, true);
}
});
return waitInfo[0]; // Might be null at this point if no report is active
}
public static void setResult(INodeBuilder node, final IStatus status) {
setResult(node, ProcessStatusConverter.toProcessStatus(status));
}
public static void setResult(INodeBuilder node, ProcessStatus status) {
if (status == null)
throw new NullPointerException("Status can't be null");
if (node == null)
throw new NullPointerException("Node can't be null");
final ProcessStatus status2 = EcoreUtil.copy(status);
node.update(new Procedure1<Node>() {
@Override
public void apply(Node arg) {
Q7Info info = getInfo(arg);
if (info.getResult() != null)
throw new IllegalStateException("Result is already set for " + arg.getName());
info.setResult(status2);
}
});
}
public static void addSnapshotWithData(INodeBuilder node, EObject data) {
Snaphot snapshot = ReportFactory.eINSTANCE.createSnaphot();
snapshot.setData(data);
node.addSnapshot(snapshot);
}
public static void takeSnapshot(INodeBuilder node) {
EventProviderManager.getInstance().takeSnapshot(node);
}
public static boolean isIterable(INodeBuilder node) {
EObject eIsIterable = node.getProperty(IQ7ReportConstants.ITERABLE);
if (eIsIterable == null) {
return false;
}
assert eIsIterable instanceof BoxedValue;
Object oIsIterable = BoxedValues.unbox((BoxedValue) eIsIterable);
assert oIsIterable instanceof Boolean;
return ((Boolean) oIsIterable).booleanValue();
}
public static void markIterable(INodeBuilder node) {
node.setProperty(IQ7ReportConstants.ITERABLE, BoxedValues.box(true));
}
}