blob: 898bc375415a48979be3550cbb150070a1a33c73 [file] [log] [blame]
/*
* 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) {
// TODO(rdayal): handle errors?
}
});
}
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;
}
}