/*
* Copyright (c) 2013, the Dart project authors.
*
* Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html
*
* 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.dart.tools.debug.core.dartium;
import com.google.dart.tools.debug.core.webkit.WebkitCallback;
import com.google.dart.tools.debug.core.webkit.WebkitPropertyDescriptor;
import com.google.dart.tools.debug.core.webkit.WebkitRemoteObject;
import com.google.dart.tools.debug.core.webkit.WebkitResult;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IIndexedValue;
import org.eclipse.debug.core.model.IVariable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* This subclass of DartiumDebugValue is used specifically for array types. The Eclipse debugging
* framework will display arrays in groups of 100 elements if it can identify which IValues are
* arrays.
*/
public class DartiumDebugIndexedValue extends DartiumDebugValue implements IIndexedValue {
DartiumDebugIndexedValue(DartiumDebugTarget target, DartiumDebugVariable variable,
WebkitRemoteObject value) {
super(target, variable, value);
}
@Override
public int getInitialOffset() {
return 0;
}
@Override
public int getSize() throws DebugException {
return value.getListLength(getTarget().getConnection());
}
@Override
public IVariable getVariable(int offset) throws DebugException {
try {
WebkitRemoteObject result = getIndexAt(value, offset);
if (result == null) {
result = WebkitRemoteObject.createNull();
}
return new DartiumDebugVariable(getTarget(), WebkitPropertyDescriptor.createIndexProperty(
offset,
result));
} catch (IOException e) {
throw createDebugException(e);
}
}
@Override
public IVariable[] getVariables(int offset, int length) throws DebugException {
IVariable[] results = new IVariable[length];
for (int i = 0; i < length; i++) {
results[i] = getVariable(offset + i);
}
return results;
}
@Override
public boolean hasVariables() throws DebugException {
return true;
}
@Override
public boolean isListValue() {
return true;
}
@Override
protected void populate() {
try {
int length = value.getListLength(getTarget().getConnection());
IVariable[] variables = getVariables(0, length);
List<IVariable> variablesList = new ArrayList<IVariable>();
for (int i = 0; i < length; i++) {
variablesList.add(variables[i]);
}
variableCollector = VariableCollector.fixed(getTarget(), variablesList);
} catch (DebugException e) {
variableCollector = VariableCollector.empty();
}
}
private WebkitRemoteObject getIndexAt(WebkitRemoteObject listObject, int offset)
throws IOException {
final WebkitRemoteObject[] results = new WebkitRemoteObject[1];
final CountDownLatch latch = new CountDownLatch(1);
getConnection().getRuntime().callFunctionOn(
listObject.getObjectId(),
"() => this[" + offset + "]",
null,
false,
new WebkitCallback<WebkitRemoteObject>() {
@Override
public void handleResult(WebkitResult<WebkitRemoteObject> result) {
results[0] = result.getResult();
latch.countDown();
}
});
try {
latch.await(3, TimeUnit.SECONDS);
} catch (InterruptedException e) {
return null;
}
return results[0];
}
}