mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
public class Test {
|
||||
<caret>
|
||||
@SuppressWarnings("unused") void m() {
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
+45
-12
@@ -86,15 +86,17 @@ public class RtfTransferableData extends AbstractSyntaxAwareInputStreamTransfera
|
||||
}
|
||||
|
||||
private static void rectangularBackground(@NotNull SyntaxInfo syntaxInfo, @NotNull StringBuilder buffer, @NotNull Runnable next) {
|
||||
buffer.append("\n\\s0\\box").append("\\cbpat").append(syntaxInfo.getDefaultBackground());
|
||||
saveBackground(buffer, syntaxInfo.getDefaultBackground());
|
||||
buffer.append("\\fs").append(syntaxInfo.getSingleFontSize() * 2).append('\n');
|
||||
buffer.append("\n\\s0\\box")
|
||||
.append("\\cbpat").append(syntaxInfo.getDefaultBackground())
|
||||
.append("\\cb").append(syntaxInfo.getDefaultBackground());
|
||||
addFontSize(buffer, syntaxInfo.getSingleFontSize());
|
||||
buffer.append('\n');
|
||||
next.run();
|
||||
buffer.append("\\par");
|
||||
}
|
||||
|
||||
private static void content(@NotNull SyntaxInfo syntaxInfo, @NotNull StringBuilder buffer, @NotNull String rawText, int maxLength) {
|
||||
MyVisitor visitor = new MyVisitor(buffer, rawText);
|
||||
MyVisitor visitor = new MyVisitor(buffer, rawText, syntaxInfo);
|
||||
SyntaxInfo.MarkupIterator it = syntaxInfo.new MarkupIterator();
|
||||
try {
|
||||
while(it.hasNext()) {
|
||||
@@ -110,8 +112,8 @@ public class RtfTransferableData extends AbstractSyntaxAwareInputStreamTransfera
|
||||
}
|
||||
}
|
||||
|
||||
private static void saveBackground(@NotNull StringBuilder buffer, int id) {
|
||||
buffer.append("\\cb").append(id);
|
||||
private static void addFontSize(StringBuilder buffer, int fontSize) {
|
||||
buffer.append("\\fs").append(fontSize * 2);
|
||||
}
|
||||
|
||||
private static class MyVisitor implements MarkupHandler {
|
||||
@@ -119,9 +121,18 @@ public class RtfTransferableData extends AbstractSyntaxAwareInputStreamTransfera
|
||||
@NotNull private final StringBuilder myBuffer;
|
||||
@NotNull private final String myRawText;
|
||||
|
||||
MyVisitor(@NotNull StringBuilder buffer, @NotNull String rawText) {
|
||||
private final int myDefaultBackgroundId;
|
||||
private final int myFontSize;
|
||||
private int myForegroundId = -1;
|
||||
private int myFontNameId = -1;
|
||||
private int myFontStyle = -1;
|
||||
|
||||
MyVisitor(@NotNull StringBuilder buffer, @NotNull String rawText, @NotNull SyntaxInfo syntaxInfo) {
|
||||
myBuffer = buffer;
|
||||
myRawText = rawText;
|
||||
|
||||
myDefaultBackgroundId = syntaxInfo.getDefaultBackground();
|
||||
myFontSize = syntaxInfo.getSingleFontSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -152,18 +163,39 @@ public class RtfTransferableData extends AbstractSyntaxAwareInputStreamTransfera
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleForeground(int foregroundId) throws Exception {
|
||||
myBuffer.append("\\cf").append(foregroundId);
|
||||
public void handleBackground(int backgroundId) throws Exception {
|
||||
if (backgroundId == myDefaultBackgroundId) {
|
||||
myBuffer.append("\\plain"); // we cannot use \chcbpat with default background id, as it doesn't work in MS Word,
|
||||
// and we cannot use \chcbpat0 as it doesn't work in OpenOffice
|
||||
|
||||
addFontSize(myBuffer, myFontSize);
|
||||
if (myFontNameId >= 0) {
|
||||
handleFont(myFontNameId);
|
||||
}
|
||||
if (myForegroundId >= 0) {
|
||||
handleForeground(myForegroundId);
|
||||
}
|
||||
if (myFontStyle >= 0) {
|
||||
handleStyle(myFontStyle);
|
||||
}
|
||||
}
|
||||
else {
|
||||
myBuffer.append("\\chcbpat").append(backgroundId);
|
||||
}
|
||||
myBuffer.append("\\cb").append(backgroundId);
|
||||
myBuffer.append('\n');
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleBackground(int backgroundId) throws Exception {
|
||||
saveBackground(myBuffer, backgroundId);
|
||||
public void handleForeground(int foregroundId) throws Exception {
|
||||
myBuffer.append("\\cf").append(foregroundId).append('\n');
|
||||
myForegroundId = foregroundId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleFont(int fontNameId) throws Exception {
|
||||
myBuffer.append("\\f").append(fontNameId);
|
||||
myBuffer.append("\\f").append(fontNameId).append('\n');
|
||||
myFontNameId = fontNameId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -177,6 +209,7 @@ public class RtfTransferableData extends AbstractSyntaxAwareInputStreamTransfera
|
||||
myBuffer.append('0');
|
||||
}
|
||||
myBuffer.append('\n');
|
||||
myFontStyle = style;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.io.StreamUtil;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.util.xmlb.XmlSerializerUtil;
|
||||
import com.intellij.util.xmlb.annotations.AbstractCollection;
|
||||
@@ -15,11 +16,16 @@ import com.intellij.util.xmlb.annotations.Property;
|
||||
import com.intellij.util.xmlb.annotations.Tag;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.net.ssl.*;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.concurrent.Callable;
|
||||
@@ -109,8 +115,10 @@ public class CertificateManager implements ApplicationComponent, PersistentState
|
||||
try {
|
||||
// Don't do this: protocol created this way will ignore SSL tunnels. See IDEA-115708.
|
||||
// Protocol.registerProtocol("https", CertificateManager.createDefault().createProtocol());
|
||||
SSLContext.setDefault(getSslContext());
|
||||
LOG.debug("Default SSL context initialized");
|
||||
if (Registry.is("ide.certificate.manager")) {
|
||||
SSLContext.setDefault(getSslContext());
|
||||
LOG.debug("Default SSL context initialized");
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
@@ -152,12 +160,21 @@ public class CertificateManager implements ApplicationComponent, PersistentState
|
||||
// SSLContext context = SSLContext.getDefault();
|
||||
// NOTE: existence of default trust manager can be checked here as
|
||||
// assert systemManager.getAcceptedIssuers().length != 0
|
||||
context.init(null, new TrustManager[]{getTrustManager()}, null);
|
||||
context.init(getDefaultKeyManagers(), new TrustManager[]{getTrustManager()}, null);
|
||||
}
|
||||
catch (Exception e) {
|
||||
catch (KeyManagementException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// IDEA-124057 Do not touch default context at all if certificate manager was disabled.
|
||||
|
||||
// For some reason passing `null` as first parameter of SSLContext#init is not enough to
|
||||
// use -Djavax.net.ssl.keyStore VM parameters, although -Djavax.net.ssl.trustStore is used
|
||||
// successfully. See this question on Stackoverflow for details
|
||||
// http://stackoverflow.com/questions/23205266/java-key-store-is-not-found-when-default-ssl-context-is-redefined
|
||||
context = getDefaultSslContext();
|
||||
}
|
||||
mySslContext = context;
|
||||
}
|
||||
return mySslContext;
|
||||
@@ -179,10 +196,75 @@ public class CertificateManager implements ApplicationComponent, PersistentState
|
||||
}
|
||||
catch (KeyManagementException e) {
|
||||
LOG.error(e);
|
||||
throw new AssertionError("Cannot initialize default SSL context");
|
||||
throw new AssertionError("Cannot initialize system SSL context");
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static SSLContext getDefaultSslContext() {
|
||||
try {
|
||||
return SSLContext.getDefault();
|
||||
}
|
||||
catch (NoSuchAlgorithmException e) {
|
||||
LOG.error("Default SSL context not available. Using system instead.");
|
||||
return getSystemSslContext();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Workaround for IDEA-124057. Manually find key store specified via VM options.
|
||||
*
|
||||
* @return key managers or {@code null} in case of any error
|
||||
*/
|
||||
@Nullable
|
||||
public static KeyManager[] getDefaultKeyManagers() {
|
||||
String keyStorePath = System.getProperty("javax.net.ssl.keyStore");
|
||||
if (keyStorePath != null) {
|
||||
LOG.info("Loading custom key store specified with VM options: " + keyStorePath);
|
||||
try {
|
||||
KeyManagerFactory factory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
||||
KeyStore keyStore;
|
||||
String keyStoreType = System.getProperty("javax.net.ssl.keyStoreType", KeyStore.getDefaultType());
|
||||
try {
|
||||
keyStore = KeyStore.getInstance(keyStoreType);
|
||||
}
|
||||
catch (KeyStoreException e) {
|
||||
if (e.getCause() instanceof NoSuchAlgorithmException) {
|
||||
LOG.error("Wrong key store type: " + keyStoreType, e);
|
||||
return null;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
String password = System.getProperty("javax.net.ssl.keyStorePassword", "");
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
inputStream = new FileInputStream(keyStorePath);
|
||||
keyStore.load(inputStream, password.toCharArray());
|
||||
factory.init(keyStore, password.toCharArray());
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
LOG.error("Key store file not found: " + keyStorePath);
|
||||
return null;
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (e.getCause() instanceof BadPaddingException) {
|
||||
LOG.error("Wrong key store password: " + password, e);
|
||||
return null;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
finally {
|
||||
StreamUtil.closeStream(inputStream);
|
||||
}
|
||||
return factory.getKeyManagers();
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getCacertsPath() {
|
||||
return myCacertsPath;
|
||||
|
||||
@@ -3,17 +3,22 @@
|
||||
|
||||
\s0\box\cbpat2\cb2\fs___PLATFORM_SPECIFIC___
|
||||
|
||||
\cf3\f1\i0\b
|
||||
\cf3
|
||||
\f1
|
||||
\i0\b
|
||||
|
||||
int \cf1\i0\b0
|
||||
int \cf1
|
||||
\i0\b0
|
||||
|
||||
field;
|
||||
\line
|
||||
|
||||
\line
|
||||
|
||||
\cf3\i0\b
|
||||
\cf3
|
||||
\i0\b
|
||||
|
||||
public static void \cf1\i0\b0
|
||||
public static void \cf1
|
||||
\i0\b0
|
||||
|
||||
main(String[] args) \{\par}
|
||||
@@ -2,31 +2,42 @@
|
||||
{\fonttbl{\f1 ___PLATFORM_SPECIFIC___;}}
|
||||
|
||||
\s0\box\cbpat2\cb2\fs___PLATFORM_SPECIFIC___
|
||||
\cf3\f1\i0\b
|
||||
\cf3
|
||||
\f1
|
||||
\i0\b
|
||||
|
||||
public class \cf1\i0\b0
|
||||
public class \cf1
|
||||
\i0\b0
|
||||
|
||||
Basic \{\line
|
||||
|
||||
\cf3\i0\b
|
||||
\cf3
|
||||
\i0\b
|
||||
|
||||
int \cf1\i0\b0
|
||||
int \cf1
|
||||
\i0\b0
|
||||
|
||||
field;\line
|
||||
|
||||
\line
|
||||
|
||||
\cf3\i0\b
|
||||
\cf3
|
||||
\i0\b
|
||||
|
||||
public static void \cf1\i0\b0
|
||||
public static void \cf1
|
||||
\i0\b0
|
||||
|
||||
main(String[] args) \{\line
|
||||
|
||||
System.out.println(\cf4\i0\b
|
||||
System.out.println(\cf4
|
||||
\i0\b
|
||||
|
||||
"Hello\cf3
|
||||
|
||||
\\t\cf4
|
||||
world!"\cf1\i0\b0
|
||||
|
||||
world!"\cf1
|
||||
\i0\b0
|
||||
|
||||
);\line
|
||||
|
||||
|
||||
@@ -4,9 +4,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.debugger.values.Value;
|
||||
|
||||
/**
|
||||
* An object that represents a variable in a call frame
|
||||
*/
|
||||
public interface Variable {
|
||||
/**
|
||||
* @return whether it is possible to read this variable
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package org.jetbrains.debugger.values;
|
||||
|
||||
import com.intellij.openapi.util.AsyncResult;
|
||||
import com.intellij.openapi.util.ActionCallback;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.debugger.Variable;
|
||||
|
||||
import java.util.List;
|
||||
@@ -18,6 +19,20 @@ public interface ArrayValue extends Value {
|
||||
*/
|
||||
int getLength();
|
||||
|
||||
@NotNull
|
||||
AsyncResult<List<Variable>> getVariables();
|
||||
/**
|
||||
* Ranges of array elements or elements if less than bucketThreshold
|
||||
*/
|
||||
@Nullable
|
||||
ActionCallback getVariables(int from, int to, int bucketThreshold, @NotNull IndexedVariablesConsumer consumer);
|
||||
|
||||
abstract class IndexedVariablesConsumer {
|
||||
// null if array is not sparse
|
||||
public abstract void consumeRanges(@Nullable int[] ranges);
|
||||
|
||||
public abstract void consumeVariables(@NotNull List<Variable> variables);
|
||||
|
||||
public boolean isObsolete() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -37,7 +37,7 @@ public abstract class ObjectValueBase<VALUE_LOADER extends ValueManager> extends
|
||||
this.valueManager = valueManager;
|
||||
}
|
||||
|
||||
protected abstract void loadProperties(@NotNull AsyncResult<List<? extends Variable>> result);
|
||||
protected abstract void loadProperties(@NotNull AsyncResult<List<Variable>> result);
|
||||
|
||||
protected final void updateCacheStamp() {
|
||||
cacheStamp = valueManager.getCacheStamp();
|
||||
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
package org.jetbrains.debugger;
|
||||
|
||||
import com.intellij.xdebugger.frame.XCompositeNode;
|
||||
import com.intellij.xdebugger.frame.XValueChildrenList;
|
||||
import com.intellij.xdebugger.frame.XValueGroup;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.debugger.values.ArrayValue;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
final class LazyVariablesGroup extends XValueGroup {
|
||||
public static final ValueGroupFactory<ArrayValue> GROUP_FACTORY = new ValueGroupFactory<ArrayValue>() {
|
||||
@Override
|
||||
public XValueGroup create(@NotNull ArrayValue value, int start, int end, @NotNull VariableContext context) {
|
||||
return new LazyVariablesGroup(value, start, end, context);
|
||||
}
|
||||
};
|
||||
|
||||
private final ArrayValue value;
|
||||
|
||||
private final int start;
|
||||
private final int end;
|
||||
private final VariableContext context;
|
||||
|
||||
public LazyVariablesGroup(@NotNull ArrayValue value, int start, int end, @NotNull VariableContext context) {
|
||||
super(String.format("[%,d \u2026 %,d]", start, end));
|
||||
|
||||
this.value = value;
|
||||
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void computeChildren(@NotNull XCompositeNode node) {
|
||||
node.setAlreadySorted(true);
|
||||
|
||||
value.getVariables(start, end, XCompositeNode.MAX_CHILDREN_TO_SHOW, new VariableView.ObsolescentIndexedVariablesConsumer(node) {
|
||||
@Override
|
||||
public void consumeRanges(@Nullable int[] ranges) {
|
||||
if (ranges == null) {
|
||||
XValueChildrenList groupList = new XValueChildrenList();
|
||||
addGroups(value, GROUP_FACTORY, groupList, start, end, XCompositeNode.MAX_CHILDREN_TO_SHOW, context);
|
||||
node.addChildren(groupList, true);
|
||||
}
|
||||
else {
|
||||
addRanges(value, ranges, node, context, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consumeVariables(@NotNull List<Variable> variables) {
|
||||
node.addChildren(Variables.createVariablesList(variables, context), true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void addRanges(@NotNull ArrayValue value, int[] ranges, @NotNull XCompositeNode node, @NotNull VariableContext context, boolean isLast) {
|
||||
XValueChildrenList groupList = new XValueChildrenList(ranges.length / 2);
|
||||
for (int i = 0, n = ranges.length; i < n; i += 2) {
|
||||
groupList.addTopGroup(new LazyVariablesGroup(value, ranges[i], ranges[i + 1], context));
|
||||
}
|
||||
node.addChildren(groupList, isLast);
|
||||
}
|
||||
|
||||
public static <T> void addGroups(@NotNull T data,
|
||||
@NotNull ValueGroupFactory<T> groupFactory,
|
||||
@NotNull XValueChildrenList groupList,
|
||||
int from,
|
||||
int limit,
|
||||
int bucketSize,
|
||||
@NotNull VariableContext context) {
|
||||
int to = Math.min(bucketSize, limit);
|
||||
boolean done = false;
|
||||
do {
|
||||
int groupFrom = from;
|
||||
int groupTo = to;
|
||||
|
||||
from += bucketSize;
|
||||
to = from + Math.min(bucketSize, limit - from);
|
||||
|
||||
// don't create group for only one member
|
||||
if (to - from == 1) {
|
||||
groupTo++;
|
||||
done = true;
|
||||
}
|
||||
groupList.addTopGroup(groupFactory.create(data, groupFrom, groupTo, context));
|
||||
if (from >= limit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (!done);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.jetbrains.debugger;
|
||||
|
||||
import com.intellij.xdebugger.frame.XValueGroup;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
interface ValueGroupFactory<T> {
|
||||
XValueGroup create(@NotNull T data, int start, int end, @NotNull VariableContext context);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.debugger;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.util.ActionCallback;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.PairConsumer;
|
||||
@@ -47,7 +48,6 @@ public final class VariableView extends XNamedValue implements VariableContext {
|
||||
|
||||
private volatile List<Variable> remainingChildren;
|
||||
private volatile int remainingChildrenOffset;
|
||||
private volatile int childrenModificationStamp;
|
||||
|
||||
public VariableView(@NotNull VariableContext context, @NotNull Variable variable) {
|
||||
super(context.getMemberFilter().normalizeMemberName(variable));
|
||||
@@ -213,44 +213,85 @@ public final class VariableView extends XNamedValue implements VariableContext {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void computeChildren(@NotNull XCompositeNode node) {
|
||||
public void computeChildren(@NotNull final XCompositeNode node) {
|
||||
node.setAlreadySorted(true);
|
||||
|
||||
if (!(value instanceof ObjectValue) || ((ObjectValue)value).hasProperties() == ThreeState.NO) {
|
||||
node.addChildren(XValueChildrenList.EMPTY, true);
|
||||
List<Variable> list = remainingChildren;
|
||||
if (list != null) {
|
||||
int to = Math.min(remainingChildrenOffset + XCompositeNode.MAX_CHILDREN_TO_SHOW, list.size());
|
||||
boolean isLast = to == list.size();
|
||||
node.addChildren(Variables.createVariablesList(list, remainingChildrenOffset, to, this), isLast);
|
||||
if (!isLast) {
|
||||
node.tooManyChildren(list.size() - to);
|
||||
remainingChildrenOffset += XCompositeNode.MAX_CHILDREN_TO_SHOW;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ObsolescentAsyncResults.consume(((ObjectValue)value).getProperties(), node, new PairConsumer<List<Variable>, XCompositeNode>() {
|
||||
boolean hasNamedProperties = value instanceof ObjectValue && ((ObjectValue)value).hasProperties() != ThreeState.NO;
|
||||
boolean hasIndexedProperties = value instanceof ArrayValue;
|
||||
ActionCallback.Chunk chunk = new ActionCallback.Chunk();
|
||||
if (hasIndexedProperties) {
|
||||
chunk.add(computeIndexedProperties((ArrayValue)value, node, !hasNamedProperties));
|
||||
}
|
||||
|
||||
if (hasNamedProperties) {
|
||||
chunk.add(computeNamedProperties((ObjectValue)value, node, !hasIndexedProperties));
|
||||
}
|
||||
|
||||
if (hasIndexedProperties == hasNamedProperties) {
|
||||
chunk.create().doWhenProcessed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!node.isObsolete()) {
|
||||
node.addChildren(XValueChildrenList.EMPTY, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class ObsolescentIndexedVariablesConsumer extends ArrayValue.IndexedVariablesConsumer {
|
||||
protected final XCompositeNode node;
|
||||
|
||||
protected ObsolescentIndexedVariablesConsumer(@NotNull XCompositeNode node) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isObsolete() {
|
||||
return node.isObsolete();
|
||||
}
|
||||
}
|
||||
|
||||
private ActionCallback computeIndexedProperties(@NotNull final ArrayValue value, @NotNull final XCompositeNode node, final boolean isLastChildren) {
|
||||
return value.getVariables(0, value.getLength(), XCompositeNode.MAX_CHILDREN_TO_SHOW, new ObsolescentIndexedVariablesConsumer(node) {
|
||||
@Override
|
||||
public void consume(List<Variable> variables, XCompositeNode node) {
|
||||
if (value instanceof ArrayValue) {
|
||||
// todo arrays could have not only indexes values
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.getType() == ValueType.ARRAY) {
|
||||
computeArrayRanges(variables, node);
|
||||
return;
|
||||
}
|
||||
|
||||
int maxPropertiesToShow;
|
||||
if (value.getType() == ValueType.FUNCTION) {
|
||||
maxPropertiesToShow = Integer.MAX_VALUE;
|
||||
public void consumeRanges(@Nullable int[] ranges) {
|
||||
if (ranges == null) {
|
||||
XValueChildrenList groupList = new XValueChildrenList();
|
||||
LazyVariablesGroup.addGroups(value, LazyVariablesGroup.GROUP_FACTORY, groupList, 0, value.getLength(), XCompositeNode.MAX_CHILDREN_TO_SHOW, VariableView.this);
|
||||
node.addChildren(groupList, isLastChildren);
|
||||
}
|
||||
else {
|
||||
maxPropertiesToShow = XCompositeNode.MAX_CHILDREN_TO_SHOW;
|
||||
List<Variable> list = remainingChildren;
|
||||
if (list != null && childrenModificationStamp == ((ObjectValue)value).getCacheStamp()) {
|
||||
int to = Math.min(remainingChildrenOffset + XCompositeNode.MAX_CHILDREN_TO_SHOW, list.size());
|
||||
boolean isLast = to == list.size();
|
||||
node.addChildren(Variables.createVariablesList(list, remainingChildrenOffset, to, VariableView.this), isLast);
|
||||
if (!isLast) {
|
||||
node.tooManyChildren(list.size() - to);
|
||||
remainingChildrenOffset += XCompositeNode.MAX_CHILDREN_TO_SHOW;
|
||||
}
|
||||
return;
|
||||
}
|
||||
LazyVariablesGroup.addRanges(value, ranges, node, VariableView.this, isLastChildren);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consumeVariables(@NotNull List<Variable> variables) {
|
||||
node.addChildren(Variables.createVariablesList(variables, VariableView.this), isLastChildren);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private ActionCallback computeNamedProperties(@NotNull final ObjectValue value, @NotNull XCompositeNode node, final boolean isLastChildren) {
|
||||
return ObsolescentAsyncResults.consume(value.getProperties(), node, new PairConsumer<List<Variable>, XCompositeNode>() {
|
||||
@Override
|
||||
public void consume(List<Variable> variables, XCompositeNode node) {
|
||||
if (value.getType() == ValueType.ARRAY && !(value instanceof ArrayValue)) {
|
||||
computeArrayRanges(variables, node);
|
||||
return;
|
||||
}
|
||||
|
||||
FunctionValue functionValue = value instanceof FunctionValue ? (FunctionValue)value : null;
|
||||
@@ -258,44 +299,21 @@ public final class VariableView extends XNamedValue implements VariableContext {
|
||||
functionValue = null;
|
||||
}
|
||||
|
||||
remainingChildren = Variables.sortFilterAndAddValueList(variables, node, VariableView.this, maxPropertiesToShow, functionValue == null);
|
||||
remainingChildren = Variables.sortFilterAndAddValueList(variables, node, VariableView.this, XCompositeNode.MAX_CHILDREN_TO_SHOW, functionValue == null);
|
||||
if (remainingChildren != null) {
|
||||
remainingChildrenOffset = maxPropertiesToShow;
|
||||
childrenModificationStamp = ((ObjectValue)value).getCacheStamp();
|
||||
remainingChildrenOffset = XCompositeNode.MAX_CHILDREN_TO_SHOW;
|
||||
}
|
||||
|
||||
if (functionValue != null) {
|
||||
// we pass context as variable context instead of this variable value - we cannot watch function scopes variables, so, this variable name doesn't matter
|
||||
node.addChildren(XValueChildrenList.bottomGroup(new FunctionScopesValueGroup(functionValue, context)), true);
|
||||
node.addChildren(XValueChildrenList.bottomGroup(new FunctionScopesValueGroup(functionValue, context)), isLastChildren);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (value instanceof ArrayValue) {
|
||||
ObsolescentAsyncResults.consume(((ArrayValue)value).getVariables(), node, new PairConsumer<List<Variable>, XCompositeNode>() {
|
||||
@Override
|
||||
public void consume(List<Variable> variables, XCompositeNode node) {
|
||||
computeIndexedValuesRanges(variables, node);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void computeIndexedValuesRanges(@NotNull List<Variable> variables, @NotNull XCompositeNode node) {
|
||||
int totalLength = variables.size();
|
||||
int bucketSize = XCompositeNode.MAX_CHILDREN_TO_SHOW;
|
||||
if (totalLength <= bucketSize) {
|
||||
node.addChildren(Variables.createVariablesList(variables, this), true);
|
||||
return;
|
||||
}
|
||||
|
||||
XValueChildrenList groupList = new XValueChildrenList();
|
||||
addGroups(variables, groupList, 0, totalLength, bucketSize);
|
||||
node.addChildren(groupList, true);
|
||||
}
|
||||
|
||||
private void computeArrayRanges(@NotNull List<? extends Variable> properties, @NotNull XCompositeNode node) {
|
||||
List<Variable> variables = Variables.filterAndSort(properties, this, false);
|
||||
final List<Variable> variables = Variables.filterAndSort(properties, this, false);
|
||||
int count = variables.size();
|
||||
int bucketSize = XCompositeNode.MAX_CHILDREN_TO_SHOW;
|
||||
if (count <= bucketSize) {
|
||||
@@ -311,7 +329,7 @@ public final class VariableView extends XNamedValue implements VariableContext {
|
||||
|
||||
XValueChildrenList groupList = new XValueChildrenList();
|
||||
if (count > 0) {
|
||||
addGroups(variables, groupList, 0, count, bucketSize);
|
||||
LazyVariablesGroup.addGroups(variables, VariablesGroup.GROUP_FACTORY, groupList, 0, count, bucketSize, this);
|
||||
}
|
||||
|
||||
int notGroupedVariablesOffset;
|
||||
@@ -323,7 +341,7 @@ public final class VariableView extends XNamedValue implements VariableContext {
|
||||
}
|
||||
|
||||
if (notGroupedVariablesOffset > 0) {
|
||||
addGroups(variables, groupList, count, notGroupedVariablesOffset, bucketSize);
|
||||
LazyVariablesGroup.addGroups(variables, VariablesGroup.GROUP_FACTORY, groupList, count, notGroupedVariablesOffset, bucketSize, this);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -337,29 +355,6 @@ public final class VariableView extends XNamedValue implements VariableContext {
|
||||
node.addChildren(groupList, true);
|
||||
}
|
||||
|
||||
private void addGroups(List<Variable> variables, XValueChildrenList groupList, int from, int limit, int bucketSize) {
|
||||
int to = Math.min(bucketSize, limit);
|
||||
boolean done = false;
|
||||
do {
|
||||
int groupFrom = from;
|
||||
int groupTo = to;
|
||||
|
||||
from += bucketSize;
|
||||
to = from + Math.min(bucketSize, limit - from);
|
||||
|
||||
// don't create group for only one member
|
||||
if (to - from == 1) {
|
||||
groupTo++;
|
||||
done = true;
|
||||
}
|
||||
groupList.addTopGroup(VariablesGroup.createArrayRangeGroup(groupFrom, groupTo, variables, this));
|
||||
if (from >= limit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (!done);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Icon getIcon() {
|
||||
return getIcon(value);
|
||||
|
||||
+19
-11
@@ -7,21 +7,29 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
public class VariablesGroup extends XValueGroup {
|
||||
private final int from;
|
||||
private final int to;
|
||||
private final List<Variable> variables;
|
||||
private final VariableContext variableContext;
|
||||
public static final ValueGroupFactory<List<Variable>> GROUP_FACTORY = new ValueGroupFactory<List<Variable>>() {
|
||||
@Override
|
||||
public XValueGroup create(@NotNull List<Variable> variables, int start, int end, @NotNull VariableContext context) {
|
||||
return createArrayRangeGroup(start, end, variables, context);
|
||||
}
|
||||
};
|
||||
|
||||
public VariablesGroup(@NotNull String name, @NotNull List<Variable> variables, VariableContext variableContext) {
|
||||
this(0, variables.size(), variables, variableContext, name);
|
||||
private final int start;
|
||||
private final int end;
|
||||
private final List<Variable> variables;
|
||||
private final VariableContext context;
|
||||
|
||||
public VariablesGroup(@NotNull String name, @NotNull List<Variable> variables, VariableContext context) {
|
||||
this(0, variables.size(), variables, context, name);
|
||||
}
|
||||
|
||||
private VariablesGroup(int from, int to, @NotNull List<Variable> variables, @NotNull VariableContext variableContext, final String name) {
|
||||
private VariablesGroup(int start, int end, @NotNull List<Variable> variables, @NotNull VariableContext context, @NotNull String name) {
|
||||
super(name);
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.variables = variables;
|
||||
this.variableContext = variableContext;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public static VariablesGroup createArrayRangeGroup(int start, int end, List<Variable> variables, VariableContext variableContext) {
|
||||
@@ -32,6 +40,6 @@ public class VariablesGroup extends XValueGroup {
|
||||
@Override
|
||||
public void computeChildren(@NotNull XCompositeNode node) {
|
||||
node.setAlreadySorted(true);
|
||||
node.addChildren(Variables.createVariablesList(variables, from, to, variableContext), true);
|
||||
node.addChildren(Variables.createVariablesList(variables, start, end, context), true);
|
||||
}
|
||||
}
|
||||
+5
@@ -174,6 +174,11 @@ public final class JsonReaderEx implements Closeable {
|
||||
this.lenient = lenient;
|
||||
}
|
||||
|
||||
public final JsonReaderEx lenient(boolean lenient) {
|
||||
this.lenient = lenient;
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public final boolean isLenient() {
|
||||
return lenient;
|
||||
|
||||
+16
@@ -1,6 +1,7 @@
|
||||
package com.intellij.tasks.integration;
|
||||
|
||||
import com.intellij.tasks.Task;
|
||||
import com.intellij.tasks.TaskBundle;
|
||||
import com.intellij.tasks.TaskManagerTestCase;
|
||||
import com.intellij.tasks.impl.LocalTaskImpl;
|
||||
import com.intellij.tasks.impl.TaskUtil;
|
||||
@@ -56,6 +57,21 @@ public class RedmineIntegrationTest extends TaskManagerTestCase {
|
||||
assertEquals("prj-1 7 7 Summary contains 'baz'", TaskUtil.getChangeListComment(localTask));
|
||||
}
|
||||
|
||||
/**
|
||||
* Redmine doesn't send 401 or 403 errors, when issues are downloaded with wrong credentials, so current user information is
|
||||
* fetched instead.
|
||||
*/
|
||||
public void testCredentialsCheck() throws Exception {
|
||||
myRepository.setPassword("wrong-password");
|
||||
try {
|
||||
myRepository.testConnection();
|
||||
fail("testConnection() should fails, when wrong credentials specified");
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertEquals(TaskBundle.message("failure.login"), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
Reference in New Issue
Block a user