/* * Copyright 2009 Google 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.google.gwt.dev.shell.remoteui; import com.google.gwt.core.ext.TreeLogger; import com.google.gwt.dev.util.Callback; import com.google.gwt.dev.util.collect.Lists; import com.google.gwt.dev.util.log.AbstractTreeLogger; import java.util.List; /** * A tree logger that creates log entries using a ViewerService. */ public final class ViewerServiceTreeLogger extends AbstractTreeLogger { private abstract class Pending { protected final Throwable caught; protected final HelpInfo helpInfo; protected final String msg; protected final TreeLogger.Type type; public Pending(Type type, String msg, Throwable caught, HelpInfo helpInfo) { this.caught = caught; this.msg = msg; this.type = type; this.helpInfo = helpInfo; } public abstract void send(); } private class PendingBranch extends Pending { public final ViewerServiceTreeLogger branch; public PendingBranch(ViewerServiceTreeLogger branch, Type type, String msg, Throwable caught, HelpInfo helpInfo) { super(type, msg, caught, helpInfo); this.branch = branch; } @Override public void send() { sendBranch(branch, type, msg, caught, helpInfo); } } private class PendingLog extends Pending { protected final int indexOfLogEntry; public PendingLog(int indexOfLogEntry, Type type, String msg, Throwable caught, HelpInfo helpInfo) { super(type, msg, caught, helpInfo); this.indexOfLogEntry = indexOfLogEntry; } @Override public void send() { sendEntry(indexOfLogEntry, type, msg, caught, helpInfo); } } private volatile int logHandle = -1; private List<Pending> pending = Lists.create(); private final ViewerServiceClient viewerServiceClient; /** * Creates a new instance with the given Viewer Service requestor. * * @param viewerServiceClient An object that can be used to make requests to a * viewer service server. */ public ViewerServiceTreeLogger(ViewerServiceClient viewerServiceClient) { this.viewerServiceClient = viewerServiceClient; } /** * Creates a new logger for a branch. Note that the logger's handle has not * been set as yet; it will only be set once the branch is committed. */ @Override protected AbstractTreeLogger doBranch() { return new ViewerServiceTreeLogger(viewerServiceClient); } @Override protected void doCommitBranch(AbstractTreeLogger childBeingCommitted, Type type, String msg, Throwable caught, HelpInfo helpInfo) { // Already synchronized via superclass. ViewerServiceTreeLogger child = (ViewerServiceTreeLogger) childBeingCommitted; if (isSent()) { // Immediately send the child branch. sendBranch(child, type, msg, caught, helpInfo); } else { // Queue the child branch until I'm committed. pending = Lists.add(pending, new PendingBranch(child, type, msg, caught, helpInfo)); } } @Override protected void doLog(int indexOfLogEntry, Type type, String msg, Throwable caught, HelpInfo helpInfo) { // Already synchronized via superclass. if (isSent()) { // Immediately send the child log entry. sendEntry(indexOfLogEntry, type, msg, caught, helpInfo); } else { // Queue the log entry until I'm committed. pending = Lists.add(pending, new PendingLog(indexOfLogEntry, type, msg, caught, helpInfo)); } } synchronized void initLogHandle(int newLogHandle) { assert !isSent(); logHandle = newLogHandle; for (Pending item : pending) { item.send(); } pending = null; } void sendBranch(final ViewerServiceTreeLogger branch, Type type, String msg, Throwable caught, HelpInfo helpInfo) { assert isSent(); viewerServiceClient.addLogBranch(branch.getBranchedIndex(), type, msg, caught, helpInfo, logHandle, new Callback<Integer>() { public void onDone(Integer result) { branch.initLogHandle(result); } public void onError(Throwable t) { System.err.println("An error occurred while attempting to add a log branch."); t.printStackTrace(System.err); } }); } void sendEntry(int indexOfLogEntry, Type type, String msg, Throwable caught, HelpInfo helpInfo) { assert isSent(); viewerServiceClient.addLogEntry(indexOfLogEntry, type, msg, caught, helpInfo, logHandle); } private boolean isSent() { return logHandle >= 0; } }