Merge remote-tracking branch 'origin/master'

This commit is contained in:
Yann Cébron
2016-09-23 19:45:43 +02:00
85 changed files with 1292 additions and 688 deletions
+1
View File
@@ -264,6 +264,7 @@
<module fileurl="file://$PROJECT_DIR$/plugins/ui-designer/ui-designer.iml" filepath="$PROJECT_DIR$/plugins/ui-designer/ui-designer.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/ui-designer-core/ui-designer-core.iml" filepath="$PROJECT_DIR$/plugins/ui-designer-core/ui-designer-core.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/ui-designer/jps-plugin/ui-designer-jps-plugin.iml" filepath="$PROJECT_DIR$/plugins/ui-designer/jps-plugin/ui-designer-jps-plugin.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/update-server-mock/update-server-mock.iml" filepath="$PROJECT_DIR$/update-server-mock/update-server-mock.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/updater/updater.iml" filepath="$PROJECT_DIR$/updater/updater.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/platform/usageView/usageView.iml" filepath="$PROJECT_DIR$/platform/usageView/usageView.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/platform/util/util.iml" filepath="$PROJECT_DIR$/platform/util/util.iml" group="platform" />
@@ -56,8 +56,7 @@ public class JavaTestLocator implements SMTestLocator {
PsiClass aClass = ClassUtil.findPsiClass(PsiManager.getInstance(project), path, null, true, scope);
if (aClass != null) {
results = ContainerUtil.newSmartList();
results.add(paramName != null ? PsiMemberParameterizedLocation.getParameterizedLocation(aClass, paramName)
: new PsiLocation<>(project, aClass));
results.add(createClassNavigatable(paramName, aClass));
}
}
else if (TEST_PROTOCOL.equals(protocol)) {
@@ -67,11 +66,16 @@ public class JavaTestLocator implements SMTestLocator {
PsiClass aClass = ClassUtil.findPsiClass(PsiManager.getInstance(project), className, null, true, scope);
if (aClass != null) {
results = ContainerUtil.newSmartList();
PsiMethod[] methods = aClass.findMethodsByName(methodName.trim(), true);
if (methods.length > 0) {
for (PsiMethod method : methods) {
results.add(paramName != null ? new PsiMemberParameterizedLocation(project, method, aClass, paramName)
: MethodLocation.elementInClass(method, aClass));
if (methodName.trim().equals(aClass.getName())) {
results.add(createClassNavigatable(paramName, aClass));
}
else {
PsiMethod[] methods = aClass.findMethodsByName(methodName.trim(), true);
if (methods.length > 0) {
for (PsiMethod method : methods) {
results.add(paramName != null ? new PsiMemberParameterizedLocation(project, method, aClass, paramName)
: MethodLocation.elementInClass(method, aClass));
}
}
}
}
@@ -80,4 +84,9 @@ public class JavaTestLocator implements SMTestLocator {
return results;
}
private Location createClassNavigatable(String paramName, @NotNull PsiClass aClass) {
return paramName != null ? PsiMemberParameterizedLocation.getParameterizedLocation(aClass, paramName)
: new PsiLocation<>(aClass.getProject(), aClass);
}
}
@@ -27,6 +27,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory;
@@ -155,6 +156,7 @@ public abstract class CreateFromUsageBaseFix extends BaseIntentionAction {
if (file == null) return null;
}
OpenFileDescriptor descriptor = new OpenFileDescriptor(project, file, textOffset);
descriptor.setScrollType(ScrollType.MAKE_VISIBLE); // avoid centering caret in editor if it's already visible
return FileEditorManager.getInstance(project).openTextEditor(descriptor, true);
}
@@ -47,7 +47,8 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.*;
import com.intellij.psi.controlFlow.ControlFlowUtil;
import com.intellij.psi.controlFlow.*;
import com.intellij.psi.controlFlow.ControlFlow;
import com.intellij.psi.impl.source.codeStyle.JavaCodeStyleManagerImpl;
import com.intellij.psi.scope.processor.VariablesProcessor;
import com.intellij.psi.scope.util.PsiScopesUtil;
@@ -1092,13 +1093,21 @@ public class ExtractMethodProcessor implements MatchProvider {
}
private boolean hasNormalExit() {
boolean hasNormalExit = false;
PsiElement lastElement = myElements[myElements.length - 1];
if (!(lastElement instanceof PsiReturnStatement || lastElement instanceof PsiBreakStatement ||
lastElement instanceof PsiContinueStatement)) {
hasNormalExit = true;
try {
PsiCodeBlock block = JavaPsiFacade.getElementFactory(myProject).createCodeBlock();
block.addRange(myElements[0], myElements[myElements.length - 1]);
ControlFlow flow = ControlFlowFactory.getInstance(myProject).getControlFlow(block, new LocalsControlFlowPolicy(block), false, false);
return ControlFlowUtil.canCompleteNormally(flow, 0, flow.getSize());
}
catch (AnalysisCanceledException e) {
//check incomplete code as simple as possible
PsiElement lastElement = myElements[myElements.length - 1];
if (!(lastElement instanceof PsiReturnStatement || lastElement instanceof PsiBreakStatement ||
lastElement instanceof PsiContinueStatement)) {
return true;
}
return false;
}
return hasNormalExit;
}
protected boolean isNeedToChangeCallContext() {
@@ -0,0 +1,17 @@
class Test {
private static void f(boolean a, boolean b) {
if (a) {
<selection>if (b) {
System.out.println("");
return;
} else {
System.out.println("");
return;
}</selection>
} else {
System.out.println("");
}
}
}
@@ -0,0 +1,22 @@
class Test {
private static void f(boolean a, boolean b) {
if (a) {
newMethod(b);
return;
} else {
System.out.println("");
}
}
private static void newMethod(boolean b) {
if (b) {
System.out.println("");
return;
} else {
System.out.println("");
return;
}
}
}
@@ -0,0 +1,17 @@
class Test {
private static void f(boolean a, boolean b) {
if (a) {
<selection>try {
System.out.println();
return;
}
catch (Exception e) {
return;
}</selection>
} else {
System.out.println("");
}
}
}
@@ -0,0 +1,22 @@
class Test {
private static void f(boolean a, boolean b) {
if (a) {
newMethod();
return;
} else {
System.out.println("");
}
}
private static void newMethod() {
try {
System.out.println();
return;
}
catch (Exception e) {
return;
}
}
}
@@ -525,12 +525,12 @@ public class InspectionProfileTest extends LightIdeaTestCase {
assertFalse(profile.isToolEnabled(HighlightDisplayKey.find("bar")));
assertFalse(profile.isToolEnabled(HighlightDisplayKey.find("disabled")));
assertTrue(profile.getToolDefaultState("bar", getProject()).isEnabled());
assertFalse(profile.getToolDefaultState("bar", getProject()).isEnabled());
assertFalse(profile.getToolDefaultState("disabled", getProject()).isEnabled());
assertEquals("<profile version=\"1.0\" is_locked=\"true\">\n" +
" <option name=\"myName\" value=\"Foo\" />\n" +
" <inspection_tool class=\"bar\" enabled=\"false\" level=\"ERROR\" enabled_by_default=\"true\" />\n" +
" <inspection_tool class=\"bar\" enabled=\"false\" level=\"ERROR\" enabled_by_default=\"false\" />\n" +
" <inspection_tool class=\"disabled\" enabled=\"false\" level=\"ERROR\" enabled_by_default=\"false\" />\n" +
" <inspection_tool class=\"foo\" enabled=\"true\" level=\"ERROR\" enabled_by_default=\"true\" />\n" +
"</profile>", serialize(profile));
@@ -623,7 +623,6 @@ public class InspectionProfileTest extends LightIdeaTestCase {
InspectionProfileImpl foo = new InspectionProfileImpl("foo", InspectionToolRegistrar.getInstance(), InspectionProjectProfileManager.getInstance(getProject()));
String test = "<profile version=\"1.0\" is_locked=\"false\">\n" +
" <option name=\"myName\" value=\"idea.default\" />\n" +
" <option name=\"myLocal\" value=\"false\" />\n" +
" <inspection_tool class=\"AbstractMethodCallInConstructor\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\" />\n" +
" <inspection_tool class=\"AssignmentToForLoopParameter\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\">\n" +
" <option name=\"m_checkForeachParameters\" value=\"false\" />\n" +
@@ -47,13 +47,11 @@ internal class InspectionSchemeTest {
"</inspections>""".trimIndent()
schemeFile.write(schemeData)
val schemeManagerFactory = SchemeManagerFactoryBase.TestSchemeManagerFactory(fsRule.fs.getPath(""))
val profileManager = ApplicationInspectionProfileManager(InspectionToolRegistrar.getInstance(),
schemeManagerFactory,
ApplicationManager.getApplication().messageBus)
val profileManager = ApplicationInspectionProfileManager(InspectionToolRegistrar.getInstance(), schemeManagerFactory, ApplicationManager.getApplication().messageBus)
profileManager.forceInitProfiles(true)
profileManager.initProfiles()
assertThat(profileManager.profiles).hasSize(1)
assertThat(profileManager.profiles).hasSize(2)
val scheme = profileManager.profiles.first() as InspectionProfileImpl
assertThat(scheme.name).isEqualTo("Bar")
@@ -868,6 +868,14 @@ public class ExtractMethodTest extends LightCodeInsightTestCase {
doTest();
}
public void testNormalExitIf() throws Exception {
doTest();
}
public void testNormalExitTry() throws Exception {
doTest();
}
public void testMethodAnnotations() throws Exception {
doTest();
}
@@ -16,9 +16,9 @@ Conversions:
0 -> new java.util.concurrent.atomic.AtomicInteger($val$) $val$
9 -> $qualifier$.set($val$) $qualifier$ = $val$ i = 9
i + 9 -> $qualifier$.get() + $val$ $qualifier$+$val$
i += 2 -> $qualifier$.getAndAdd(($val$)) $qualifier$ += $val$
i += 2 -> $qualifier$.addAndGet($val$) $qualifier$ += $val$
i - 9 -> $qualifier$.get() - $val$ $qualifier$-$val$
i -= 5 -> $qualifier$.getAndAdd(-($val$)) $qualifier$ -= $val$
i -= 5 -> $qualifier$.addAndGet(-($val$)) $qualifier$ -= $val$
i == 0 -> $qualifier$.get() == $val$ $qualifier$==$val$
New expression type changes:
@@ -4,8 +4,8 @@ class Test {
AtomicInteger i = new AtomicInteger(0);
void foo() {
i.getAndAdd((2));
i.getAndAdd(-(5));
i.addAndGet(2);
i.addAndGet(-5);
if (i.get() == 0) {
i.set(9);
}
@@ -31,7 +31,6 @@ import org.jdom.Element;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
@@ -49,10 +48,7 @@ public class InspectionProfileConvertor {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettingsConvertor");
@NonNls private static final String INSPECTIONS_TAG = "inspections";
@NonNls private static final String NAME_ATT = "name";
@NonNls private static final String INSP_TOOL_TAG = "inspection_tool";
@NonNls private static final String CLASS_ATT = "class";
@NonNls private static final String VERSION_ATT = "version";
@NonNls private static final String PROFILE_NAME_ATT = "profile_name";
@NonNls private static final String OPTION_TAG = "option";
@@ -102,23 +98,6 @@ public class InspectionProfileConvertor {
}
}
public static Element convertToNewFormat(Element profileFile, InspectionProfile profile) {
Element rootElement = new Element(INSPECTIONS_TAG);
rootElement.setAttribute(NAME_ATT, profile.getName());
final InspectionToolWrapper[] tools = profile.getInspectionTools(null);
for (final Object o : profileFile.getChildren(INSP_TOOL_TAG)) {
Element toolElement = ((Element)o).clone();
String toolClassName = toolElement.getAttributeValue(CLASS_ATT);
final String shortName = convertToShortName(toolClassName, tools);
if (shortName == null) {
continue;
}
toolElement.setAttribute(CLASS_ATT, shortName);
rootElement.addContent(toolElement);
}
return rootElement;
}
private static void renameOldDefaultsProfile() {
String directoryPath = PathManager.getConfigPath() + File.separator + InspectionProfileManager.INSPECTION_DIR;
File profileDirectory = new File(directoryPath);
@@ -170,15 +149,4 @@ public class InspectionProfileConvertor {
profile.setErrorLevel(key, level, null);
}
}
@Nullable
private static String convertToShortName(String displayName, InspectionToolWrapper[] tools) {
if (displayName == null) return null;
for (InspectionToolWrapper tool : tools) {
if (displayName.equals(tool.getDisplayName())) {
return tool.getShortName();
}
}
return null;
}
}
@@ -25,6 +25,13 @@ public abstract class HighlightingLevelManager {
return ServiceManager.getService(project, HighlightingLevelManager.class);
}
/**
* >= Syntax level
*/
public abstract boolean shouldHighlight(@NotNull PsiElement psiRoot);
/**
* >= Inspections level
*/
public abstract boolean shouldInspect(@NotNull PsiElement psiRoot);
}
@@ -17,7 +17,6 @@ package com.intellij.codeInspection.ex;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInsight.daemon.InspectionProfileConvertor;
import com.intellij.codeInspection.InspectionEP;
import com.intellij.codeInspection.InspectionProfile;
import com.intellij.codeInspection.InspectionProfileEntry;
@@ -58,7 +57,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author max
@@ -126,6 +124,13 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
myProfileManager = profileManager;
}
public InspectionProfileImpl(@NotNull String profileName,
@NotNull InspectionToolRegistrar registrar,
@NotNull ProfileManager profileManager,
@Nullable SchemeDataHolder<? super InspectionProfileImpl> dataHolder) {
this(profileName, registrar, profileManager, getDefaultProfile(), dataHolder);
}
@NotNull
public static InspectionProfileImpl createSimple(@NotNull String name,
@NotNull Project project,
@@ -225,20 +230,41 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
public void readExternal(@NotNull Element element) {
super.readExternal(element);
final String version = element.getAttributeValue(VERSION_TAG);
if (version == null || !version.equals(VALID_VERSION)) {
element = InspectionProfileConvertor.convertToNewFormat(element, this);
}
final Element highlightElement = element.getChild(USED_LEVELS);
if (highlightElement != null) {
// from old profiles
((SeverityProvider)getProfileManager()).getOwnSeverityRegistrar().readExternal(highlightElement);
}
for (Element toolElement : element.getChildren(INSPECTION_TOOL_TAG)) {
myUninitializedSettings.put(toolElement.getAttributeValue(CLASS_TAG), toolElement.clone());
String version = element.getAttributeValue(VERSION_TAG);
if (version == null || !version.equals(VALID_VERSION)) {
InspectionToolWrapper[] tools = getInspectionTools(null);
for (Element toolElement : element.getChildren("inspection_tool")) {
String toolClassName = toolElement.getAttributeValue(CLASS_TAG);
String shortName = convertToShortName(toolClassName, tools);
if (shortName == null) {
continue;
}
toolElement.setAttribute(CLASS_TAG, shortName);
myUninitializedSettings.put(shortName, toolElement.clone());
}
}
else {
for (Element toolElement : element.getChildren(INSPECTION_TOOL_TAG)) {
myUninitializedSettings.put(toolElement.getAttributeValue(CLASS_TAG), toolElement.clone());
}
}
}
@Nullable
private static String convertToShortName(@Nullable String displayName, InspectionToolWrapper[] tools) {
if (displayName == null) return null;
for (InspectionToolWrapper tool : tools) {
if (displayName.equals(tool.getDisplayName())) {
return tool.getShortName();
}
}
return null;
}
@NotNull
@@ -259,10 +285,11 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
return myDataHolder.read();
}
Element result = isProjectLevel() ? new Element("profile").setAttribute("version", "1.0") : new Element("inspections").setAttribute("profile_name", getName());
Element element = new Element("profile");
Element result = isProjectLevel() ? element.setAttribute("version", "1.0") : element.setAttribute("profile_name", getName());
serializeInto(result, false);
if (myProfileManager instanceof ProjectInspectionProfileManager && ProjectKt.isDirectoryBased(((ProjectInspectionProfileManager)myProfileManager).getProject())) {
if (isProjectLevel() && ProjectKt.isDirectoryBased(((ProjectInspectionProfileManager)myProfileManager).getProject())) {
return new Element("component").setAttribute("name", "InspectionProjectProfileManager").addContent(result);
}
return result;
@@ -549,7 +576,12 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
final List<InspectionToolWrapper> tools;
try {
tools = createTools(project);
if (mySource == null) {
tools = myRegistrar.createTools();
}
else {
tools = ContainerUtil.map(mySource.getDefaultStates(project), ScopeToolState::getTool);
}
}
catch (ProcessCanceledException ignored) {
return;
@@ -611,7 +643,6 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
: HighlightDisplayLevel.DO_NOT_SHOW;
HighlightDisplayLevel defaultLevel = toolWrapper.getDefaultLevel();
HighlightDisplayLevel level = baseLevel.getSeverity().compareTo(defaultLevel.getSeverity()) > 0 ? baseLevel : defaultLevel;
//HighlightDisplayLevel level = myBaseProfile != null && myBaseProfile.getTools(shortName, project) != null ? myBaseProfile.getErrorLevel(key, project) : toolWrapper.getDefaultLevel();
boolean enabled = myBaseProfile != null ? myBaseProfile.isToolEnabled(key) : toolWrapper.isEnabledByDefault();
final ToolsImpl toolsList = new ToolsImpl(toolWrapper, level, !myLockedProfile && enabled, enabled);
final Element element = myUninitializedSettings.remove(shortName);
@@ -621,10 +652,15 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
}
else if (!myUninitializedSettings.containsKey(InspectionElementsMergerBase.getMergedMarkerName(shortName))) {
final InspectionElementsMergerBase merger = getMerger(shortName);
if (merger != null) {
final Element merged = merger.merge(myUninitializedSettings);
if (merged != null) {
toolsList.readExternal(merged, this, dependencies);
Element merged = merger == null ? null : merger.merge(myUninitializedSettings);
if (merged != null) {
toolsList.readExternal(merged, this, dependencies);
}
else if (isProfileLocked()) {
// https://youtrack.jetbrains.com/issue/IDEA-158936
toolsList.setEnabled(false);
if (toolsList.getNonDefaultTools() == null) {
toolsList.getDefaultState().setEnabled(false);
}
}
}
@@ -664,14 +700,6 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
myScopesOrder = scopesOrder;
}
@NotNull
private List<InspectionToolWrapper> createTools(@Nullable Project project) {
if (mySource != null) {
return ContainerUtil.map(mySource.getDefaultStates(project), ScopeToolState::getTool);
}
return myRegistrar.createTools();
}
private HighlightDisplayLevel getErrorLevel(@NotNull HighlightDisplayKey key, @Nullable Project project) {
final ToolsImpl tools = getTools(key.toString(), project);
LOG.assertTrue(tools != null, "profile name: " + myName + " base profile: " + (myBaseProfile != null ? myBaseProfile.getName() : "-") + " key: " + key);
@@ -888,7 +916,11 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
@NotNull
public List<ScopeToolState> getDefaultStates(@Nullable Project project) {
initInspectionTools(project);
return myTools.values().stream().map(Tools::getDefaultState).collect(Collectors.toList());
List<ScopeToolState> result = new ArrayList<>();
for (Tools tools : myTools.values()) {
result.add(tools.getDefaultState());
}
return result;
}
@NotNull
@@ -35,10 +35,6 @@ public abstract class ProfileEx implements Profile {
@NotNull
protected String myName;
@OptionTag("myLocal")
// exists only to preserve compatibility
private boolean myLocal;
protected ProfileManager myProfileManager;
private boolean myIsProjectLevel;
@@ -24,34 +24,33 @@ import com.intellij.profile.Profile;
import com.intellij.profile.ProfileManager;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
public class InspectionProfileLoadUtil {
@NonNls public static final String PROFILE_NAME_TAG = "profile_name";
@NonNls public static final String PROFILE_TAG = "profile";
private static String getProfileName(@NotNull File file, @NotNull Element element) {
String name = getRootElementAttribute(PROFILE_NAME_TAG, element);
String name = null;
for (Element option : element.getChildren("option")) {
if ("myName".equals(option.getAttributeValue("name"))) {
name = option.getAttributeValue("value");
}
}
if (name == null) {
//noinspection deprecation
name = element.getAttributeValue("profile_name");
}
return name != null ? name : FileUtil.getNameWithoutExtension(file);
}
@Nullable
private static String getRootElementAttribute(@NonNls String name, @NotNull Element element) {
return element.getAttributeValue(name);
}
@NotNull
public static Profile load(@NotNull File file,
@NotNull InspectionToolRegistrar registrar,
@NotNull ProfileManager profileManager) throws JDOMException, IOException, InvalidDataException {
Element element = JDOMUtil.load(file);
InspectionProfileImpl profile = new InspectionProfileImpl(getProfileName(file, element), registrar, profileManager);
final Element profileElement = element.getChild(PROFILE_TAG);
final Element profileElement = element.getChild("profile");
if (profileElement != null) {
element = profileElement;
}
@@ -96,7 +96,8 @@ class ProjectInspectionProfileManager(val project: Project,
override val schemeManager = schemeManagerFactory.create("inspectionProfiles", object : InspectionProfileProcessor() {
override fun createScheme(dataHolder: SchemeDataHolder<InspectionProfileImpl>,
name: String,
attributeProvider: Function<String, String?>): InspectionProfileImpl {
attributeProvider: Function<String, String?>,
isBundled: Boolean): InspectionProfileImpl {
val profile = InspectionProfileImpl(name, InspectionToolRegistrar.getInstance(), this@ProjectInspectionProfileManager,
InspectionProfileImpl.getDefaultProfile(), dataHolder)
profile.isProjectLevel = true
@@ -38,17 +38,18 @@ import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent
import com.intellij.openapi.vfs.newvfs.events.VFileCreateEvent
import com.intellij.openapi.vfs.newvfs.events.VFileDeleteEvent
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
import com.intellij.util.*
import com.intellij.util.PathUtil
import com.intellij.util.PathUtilRt
import com.intellij.util.SmartList
import com.intellij.util.containers.ConcurrentList
import com.intellij.util.containers.ContainerUtil
import com.intellij.util.io.*
import com.intellij.util.loadElement
import com.intellij.util.messages.MessageBus
import com.intellij.util.text.UniqueNameGenerator
import gnu.trove.THashSet
import org.jdom.Document
import org.jdom.Element
import org.xmlpull.mxp1.MXParser
import org.xmlpull.v1.XmlPullParser
import java.io.File
import java.io.IOException
import java.io.InputStream
@@ -97,7 +98,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
init {
if (processor is SchemeExtensionProvider) {
schemeExtension = processor.schemeExtension
updateExtension = processor.isUpgradeNeeded
updateExtension = true
}
else {
schemeExtension = FileStorageCoreUtil.DEFAULT_EXT
@@ -219,7 +220,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
directory.refresh(true, false)
}
override fun loadBundledScheme(resourceName: String, requestor: Any, convertor: ThrowableConvertor<Element, T, Throwable>) {
override fun loadBundledScheme(resourceName: String, requestor: Any) {
try {
val url = if (requestor is AbstractExtensionPointBean)
requestor.loaderForClass.getResource(resourceName)
@@ -230,23 +231,25 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
return
}
val element = loadElement(URLUtil.openStream(url))
val scheme = convertor.convert(element)
if (processor.isExternalizable(scheme)) {
val bytes = URLUtil.openStream(url).readBytes()
lazyPreloadScheme(bytes, isUseOldFileNameSanitize) { name, parser ->
val attributeProvider = Function<String, String?> { parser.getAttributeValue(null, it) }
val schemeName = name ?: (processor as LazySchemeProcessor).getName(attributeProvider)
val fileName = PathUtilRt.getFileName(url.path)
val extension = getFileExtension(fileName, true)
val info = ExternalInfo(fileName.substring(0, fileName.length - extension.length), extension)
info.digest = element.digest()
info.schemeName = scheme.name
val oldInfo = schemeToInfo.put(scheme, info)
val externalInfo = ExternalInfo(fileName.substring(0, fileName.length - extension.length), extension)
externalInfo.schemeName = schemeName
val scheme = (processor as LazySchemeProcessor).createScheme(SchemeDataHolderImpl(bytes, externalInfo), schemeName, attributeProvider, true)
val oldInfo = schemeToInfo.put(scheme, externalInfo)
LOG.assertTrue(oldInfo == null)
val oldScheme = readOnlyExternalizableSchemes.put(scheme.name, scheme)
if (oldScheme != null) {
LOG.warn("Duplicated scheme ${scheme.name} - old: $oldScheme, new $scheme")
}
schemes.add(scheme)
}
schemes.add(scheme)
}
catch (e: Throwable) {
LOG.error("Cannot read scheme from $resourceName", e)
@@ -434,53 +437,23 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
var scheme: MUTABLE_SCHEME? = null
if (processor is LazySchemeProcessor) {
val bytes = input.readBytes()
val parser = MXParser()
parser.setInput(bytes.inputStream().reader())
var eventType = parser.eventType
read@ do {
when (eventType) {
XmlPullParser.START_TAG -> {
if (!isUseOldFileNameSanitize || parser.name != "component") {
var name: String? = null
if (isUseOldFileNameSanitize && (parser.name == "profile" || parser.name == "copyright")) {
eventType = parser.next()
findName@ while (eventType != XmlPullParser.END_DOCUMENT) {
when (eventType) {
XmlPullParser.START_TAG -> {
if (parser.name == "option" && parser.getAttributeValue(null, "name") == "myName") {
name = parser.getAttributeValue(null, "value")
break@findName
}
}
}
eventType = parser.next()
}
}
val attributeProvider = Function<String, String?> { parser.getAttributeValue(null, it) }
val schemeName = name ?: processor.getName(attributeProvider)
if (!checkExisting(schemeName)) {
return null
}
val externalInfo = createInfo(schemeName, null)
val dataHolder = SchemeDataHolderImpl(bytes, externalInfo)
scheme = processor.createScheme(dataHolder, schemeName, attributeProvider)
schemeToInfo.put(scheme, externalInfo)
this.filesToDelete.remove(fileName)
break@read
}
}
lazyPreloadScheme(bytes, isUseOldFileNameSanitize) { name, parser ->
val attributeProvider = Function<String, String?> { parser.getAttributeValue(null, it) }
val schemeName = name ?: processor.getName(attributeProvider)
if (!checkExisting(schemeName)) {
return null
}
eventType = parser.next()
val externalInfo = createInfo(schemeName, null)
scheme = processor.createScheme(SchemeDataHolderImpl(bytes, externalInfo), schemeName, attributeProvider)
schemeToInfo.put(scheme, externalInfo)
this.filesToDelete.remove(fileName)
}
while (eventType != XmlPullParser.END_DOCUMENT)
}
else {
val element = loadElement(input)
scheme = (processor as NonLazySchemeProcessor).readScheme(element, duringLoad) ?: return null
val schemeName = scheme.name
val schemeName = scheme!!.name
if (!checkExisting(schemeName)) {
return null
}
@@ -0,0 +1,52 @@
package com.intellij.configurationStore
import org.xmlpull.mxp1.MXParser
import org.xmlpull.v1.XmlPullParser
internal inline fun lazyPreloadScheme(bytes: ByteArray, isUseOldFileNameSanitize: Boolean, consumer: (name: String?, parser: XmlPullParser) -> Unit) {
val parser = MXParser()
parser.setInput(bytes.inputStream().reader())
consumer(preload(isUseOldFileNameSanitize, parser), parser)
}
private fun preload(isUseOldFileNameSanitize: Boolean, parser: MXParser): String? {
var eventType = parser.eventType
fun findName(): String? {
eventType = parser.next()
while (eventType != XmlPullParser.END_DOCUMENT) {
when (eventType) {
XmlPullParser.START_TAG -> {
if (parser.name == "option" && parser.getAttributeValue(null, "name") == "myName") {
return parser.getAttributeValue(null, "value")
}
}
}
eventType = parser.next()
}
return null
}
do {
when (eventType) {
XmlPullParser.START_TAG -> {
if (!isUseOldFileNameSanitize || parser.name != "component") {
if (parser.name == "profile" || (isUseOldFileNameSanitize && parser.name == "copyright")) {
return findName()
}
else if (parser.name == "inspections") {
// backward compatibility - we don't write PROFILE_NAME_TAG anymore
return parser.getAttributeValue(null, "profile_name") ?: findName()
}
else {
return null
}
}
}
}
eventType = parser.next()
}
while (eventType != XmlPullParser.END_DOCUMENT)
return null
}
@@ -15,7 +15,6 @@
*/
package com.intellij.configurationStore
import com.intellij.openapi.options.BaseSchemeProcessor
import com.intellij.openapi.options.ExternalizableScheme
import com.intellij.openapi.options.SchemeManagerFactory
import com.intellij.openapi.util.io.FileUtil
@@ -36,12 +35,12 @@ import com.intellij.util.xmlb.serialize
import gnu.trove.THashMap
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.jdom.Element
import org.junit.ClassRule
import org.junit.Rule
import org.junit.Test
import java.io.File
import java.nio.file.Path
import java.util.function.Function
internal val FILE_SPEC = "REMOTE"
@@ -155,11 +154,11 @@ internal class SchemeManagerTest {
scheme.save(dir.resolve("1.icls"))
TestScheme("local", "false").save(dir.resolve("1.xml"))
val schemesManager = SchemeManagerImpl(FILE_SPEC, object: TestSchemesProcessor() {
override val isUpgradeNeeded = true
class ATestSchemesProcessor : TestSchemesProcessor(), SchemeExtensionProvider {
override val schemeExtension = ".icls"
}, null, dir)
}
val schemesManager = SchemeManagerImpl(FILE_SPEC, ATestSchemesProcessor(), null, dir)
schemesManager.loadSchemes()
assertThat(schemesManager.allSchemes).containsOnly(scheme)
@@ -219,9 +218,8 @@ internal class SchemeManagerTest {
@Test fun `save only if scheme differs from bundled`() {
val dir = tempDirManager.newPath()
var schemeManager = createSchemeManager(dir)
val converter: (Element) -> TestScheme = { XmlSerializer.deserialize(it, TestScheme::class.java)!! }
val bundledPath = "/com/intellij/configurationStore/bundledSchemes/default"
schemeManager.loadBundledScheme(bundledPath, this, converter)
schemeManager.loadBundledScheme(bundledPath, this)
val customScheme = TestScheme("default")
assertThat(schemeManager.allSchemes).containsOnly(customScheme)
@@ -239,7 +237,7 @@ internal class SchemeManagerTest {
assertThat(dir.resolve("default.xml")).isRegularFile()
schemeManager = createSchemeManager(dir)
schemeManager.loadBundledScheme(bundledPath, this, converter)
schemeManager.loadBundledScheme(bundledPath, this)
schemeManager.loadSchemes()
assertThat(schemeManager.allSchemes).containsOnly(customScheme)
@@ -375,27 +373,33 @@ private fun checkSchemes(baseDir: Path, expected: String, ignoreDeleted: Boolean
}
baseDir.directoryStreamIfExists {
val schemesProcessor = TestSchemesProcessor()
for (file in it) {
val scheme = schemesProcessor.readScheme(loadElement(file), true)!!
val scheme = XmlSerializer.deserialize(loadElement(file), TestScheme::class.java)!!
assertThat(fileToSchemeMap.get(FileUtil.getNameWithoutExtension(file.fileName.toString()))).isEqualTo(scheme.name)
}
}
}
@Tag("scheme")
data class TestScheme(@field:com.intellij.util.xmlb.annotations.Attribute @field:kotlin.jvm.JvmField var name: String = "", @field:com.intellij.util.xmlb.annotations.Attribute var data: String? = null) : ExternalizableScheme {
data class TestScheme(@field:com.intellij.util.xmlb.annotations.Attribute @field:kotlin.jvm.JvmField var name: String = "", @field:com.intellij.util.xmlb.annotations.Attribute var data: String? = null) : ExternalizableScheme, SerializableScheme {
override fun getName() = name
override fun setName(value: String) {
name = value
}
override fun writeScheme() = serialize()
}
open class TestSchemesProcessor : BaseSchemeProcessor<TestScheme, TestScheme>() {
override fun readScheme(element: Element, duringLoad: Boolean) = XmlSerializer.deserialize(element, TestScheme::class.java)
override fun writeScheme(scheme: TestScheme) = scheme.serialize()
open class TestSchemesProcessor : LazySchemeProcessor<TestScheme, TestScheme>() {
override fun createScheme(dataHolder: SchemeDataHolder<TestScheme>,
name: String,
attributeProvider: Function<String, String?>,
isBundled: Boolean): TestScheme {
val scheme = XmlSerializer.deserialize(dataHolder.read(), TestScheme::class.java)!!
dataHolder.updateDigest(scheme)
return scheme
}
}
fun SchemeManagerImpl<*, *>.save() {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,12 +15,15 @@
*/
package com.intellij.openapi.editor.colors.impl;
import com.intellij.configurationStore.SerializableScheme;
import com.intellij.openapi.editor.colors.ColorKey;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.options.ExternalizableScheme;
import com.intellij.openapi.util.Comparing;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
@@ -28,7 +31,7 @@ import java.awt.*;
/**
* @author Yura Cangea
*/
public class EditorColorsSchemeImpl extends AbstractColorsScheme implements ExternalizableScheme {
public class EditorColorsSchemeImpl extends AbstractColorsScheme implements ExternalizableScheme, SerializableScheme {
public EditorColorsSchemeImpl(EditorColorsScheme parentScheme) {
super(parentScheme);
}
@@ -83,4 +86,12 @@ public class EditorColorsSchemeImpl extends AbstractColorsScheme implements Exte
newScheme.setDefaultMetaInfo(this);
return newScheme;
}
@NotNull
@Override
public Element writeScheme() {
Element root = new Element("scheme");
writeExternal(root);
return root;
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

@@ -20,9 +20,11 @@ import com.intellij.ide.DataManager;
import com.intellij.ide.util.scopeChooser.EditScopesDialog;
import com.intellij.ide.util.scopeChooser.ScopeChooserConfigurable;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.options.ex.Settings;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.util.ui.JBUI;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -56,9 +58,7 @@ class ScopeColorsPageFactory implements ColorAndFontPanelFactory {
//panel.setBorder(new LineBorder(Color.red));
if (projects.length == 0) return panel;
GridBagConstraints gc = new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
new Insets(0, 0, 0, 0), 0, 0);
final Project contextProject = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext());
final Project project = contextProject != null ? contextProject : projects[0];
JBUI.emptyInsets(), 0, 0);
JButton button = new JButton("Manage Scopes...");
button.setPreferredSize(new Dimension(230, button.getPreferredSize().height));
@@ -74,7 +74,9 @@ class ScopeColorsPageFactory implements ColorAndFontPanelFactory {
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(@NotNull ActionEvent e) {
Settings settings = Settings.KEY.getData(DataManager.getInstance().getDataContext());
DataContext context = DataManager.getInstance().getDataContext(panel);
Settings settings = Settings.KEY.getData(context);
Project project = CommonDataKeys.PROJECT.getData(context);
if (settings != null) {
try {
if (settings.select(settings.find(ScopeChooserConfigurable.PROJECT_SCOPES)).isRejected()) {
@@ -191,7 +191,7 @@ public class HectorComponent extends JPanel {
@Override
public Dimension getPreferredSize() {
final Dimension preferredSize = super.getPreferredSize();
final int width = 300;
final int width = JBUI.scale(300);
if (preferredSize.width < width){
preferredSize.width = width;
}
@@ -24,6 +24,7 @@ import com.intellij.codeInsight.daemon.impl.SeverityRegistrar;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightingSettingsPerFile;
import com.intellij.codeInspection.InspectionProfile;
import com.intellij.codeInspection.InspectionsBundle;
import com.intellij.configurationStore.BundledSchemeEP;
import com.intellij.configurationStore.SchemeDataHolder;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.application.ApplicationManager;
@@ -33,6 +34,7 @@ import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.options.SchemeManager;
import com.intellij.openapi.options.SchemeManagerFactory;
@@ -40,6 +42,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.ui.Messages;
import com.intellij.profile.Profile;
import com.intellij.profile.ProfileManager;
import com.intellij.profile.codeInspection.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ObjectUtils;
@@ -72,6 +75,8 @@ import static com.intellij.codeInspection.ex.InspectionProfileImpl.getDefaultPro
public class ApplicationInspectionProfileManager extends BaseInspectionProfileManager implements InspectionProfileManager,
SeverityProvider,
PersistentStateComponent<Element> {
private static final ExtensionPointName<BundledSchemeEP> BUNDLED_EP_NAME = ExtensionPointName.create("com.intellij.bundledInspectionProfile");
private final InspectionToolRegistrar myRegistrar;
private final SchemeManager<InspectionProfileImpl> mySchemeManager;
private final AtomicBoolean myProfilesAreInitialized = new AtomicBoolean(false);
@@ -90,14 +95,20 @@ public class ApplicationInspectionProfileManager extends BaseInspectionProfileMa
@NotNull
@Override
public String getName(@NotNull Function<String, String> attributeProvider) {
return ObjectUtils.chooseNotNull(attributeProvider.apply(InspectionProfileLoadUtil.PROFILE_NAME_TAG), "unnamed");
return "unnamed";
}
@NotNull
public InspectionProfileImpl createScheme(@NotNull SchemeDataHolder<? super InspectionProfileImpl> dataHolder,
@NotNull String name,
@NotNull Function<String, String> attributeProvider) {
return new InspectionProfileImpl(name, myRegistrar, ApplicationInspectionProfileManager.this, getDefaultProfile(), dataHolder);
@NotNull Function<String, String> attributeProvider,
boolean isBundled) {
if (isBundled) {
return new BundledInspectionProfile(name, myRegistrar, ApplicationInspectionProfileManager.this, dataHolder);
}
else {
return new InspectionProfileImpl(name, myRegistrar, ApplicationInspectionProfileManager.this, dataHolder);
}
}
@Override
@@ -160,22 +171,43 @@ public class ApplicationInspectionProfileManager extends BaseInspectionProfileMa
}
public void initProfiles() {
if (myProfilesAreInitialized.getAndSet(true)) {
if (mySchemeManager.isEmpty()) {
createDefaultProfile();
}
if (!myProfilesAreInitialized.compareAndSet(false, true)) {
return;
}
if (!LOAD_PROFILES) return;
loadBundledSchemes();
mySchemeManager.loadSchemes();
if (mySchemeManager.isEmpty()) {
createDefaultProfile();
}
createDefaultProfile();
}
private void createDefaultProfile() {
getSchemeManager().addScheme(createSampleProfile(InspectionProfileImpl.DEFAULT_PROFILE_NAME, getDefaultProfile()));
final InspectionProfileImpl oldDefault = mySchemeManager.findSchemeByName(InspectionProfileImpl.DEFAULT_PROFILE_NAME);
if (oldDefault == null || !oldDefault.isProfileLocked()) {
getSchemeManager().addScheme(createSampleProfile(InspectionProfileImpl.DEFAULT_PROFILE_NAME, getDefaultProfile()));
}
}
private void loadBundledSchemes() {
if (!isUnitTestOrHeadlessMode()) {
for (BundledSchemeEP ep : BUNDLED_EP_NAME.getExtensions()) {
mySchemeManager.loadBundledScheme(ep.getPath() + ".xml", ep);
}
}
}
private static class BundledInspectionProfile extends InspectionProfileImpl {
public BundledInspectionProfile(@NotNull String profileName,
@NotNull InspectionToolRegistrar registrar,
@NotNull ProfileManager profileManager,
@Nullable SchemeDataHolder<? super InspectionProfileImpl> dataHolder) {
super(profileName, registrar, profileManager, dataHolder);
}
}
private static boolean isUnitTestOrHeadlessMode() {
return ApplicationManager.getApplication().isUnitTestMode() || ApplicationManager.getApplication().isHeadlessEnvironment();
}
public Profile loadProfile(@NotNull String path) throws IOException, JDOMException {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -172,11 +172,11 @@ public class ExportHTMLAction extends AnAction implements DumbAware {
if (profileName != null) {
element.setAttribute(InspectionApplication.PROFILE, profileName);
}
JDOMUtil.writeDocument(new Document(element),
outputDirectoryName + File.separator + InspectionApplication.DESCRIPTIONS + InspectionApplication.XML_EXTENSION,
JDOMUtil.writeParent(element,
new File(outputDirectoryName, InspectionApplication.DESCRIPTIONS + InspectionApplication.XML_EXTENSION),
CodeStyleSettingsManager.getSettings(null).getLineSeparator());
}
catch (final IOException e) {
catch (IOException e) {
ApplicationManager.getApplication().invokeLater(() -> Messages.showErrorDialog(myView, e.getMessage()));
}
}
@@ -49,11 +49,6 @@ public class QuickChangeInspectionProfileAction extends QuickSwitchSchemeAction
});
}
@Override
protected boolean isEnabled() {
return true;
}
@Override
public void update(@NotNull AnActionEvent e) {
final Project project = getEventProject(e);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -44,9 +44,4 @@ public class AddToFavoritesPopupAction extends QuickSwitchSchemeAction implement
}
group.add(new AddToNewFavoritesListAction());
}
@Override
protected boolean isEnabled() {
return true;
}
}
@@ -38,7 +38,10 @@ import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
@@ -51,10 +54,8 @@ import com.intellij.profile.codeInspection.ui.ErrorsConfigurable;
import com.intellij.profile.codeInspection.ui.SingleInspectionProfilePanel;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.util.Alarm;
import com.intellij.util.SystemProperties;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NotNull;
@@ -70,6 +71,8 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static com.intellij.openapi.util.io.FileUtil.sanitizeFileName;
public abstract class InspectionToolsConfigurable extends BaseConfigurable
implements ErrorsConfigurable, SearchableConfigurable, Configurable.NoScroll {
public static final String ID = "Errors";
@@ -337,26 +340,23 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable
@Override
public void export() {
final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
descriptor.setDescription("Choose directory to store profile file");
FileChooser.chooseFile(descriptor, getProject(), wholePanel, null, file -> {
final Element element = new Element("inspections");
FileChooser.chooseFile(descriptor, getProject(), wholePanel, null, dir -> {
try {
final SingleInspectionProfilePanel panel = getSelectedPanel();
SingleInspectionProfilePanel panel = getSelectedPanel();
LOG.assertTrue(panel != null);
final InspectionProfileImpl profile = getSelectedObject();
InspectionProfileImpl profile = getSelectedObject();
LOG.assertTrue(true);
profile.writeExternal(element);
final String filePath =
FileUtil.toSystemDependentName(file.getPath()) + File.separator + FileUtil.sanitizeFileName(profile.getName()) + ".xml";
if (new File(filePath).isFile()) {
if (Messages
.showOkCancelDialog(wholePanel, "File \'" + filePath + "\' already exist. Do you want to overwrite it?", "Warning",
Messages.getQuestionIcon()) != Messages.OK) {
return;
}
Element element = profile.writeScheme();
File file = new File(FileUtil.toSystemDependentName(dir.getPath()), sanitizeFileName(profile.getName()) + ".xml");
if (file.isFile() &&
Messages.showOkCancelDialog(wholePanel, "File \'" + file + "\' already exist. Do you want to overwrite it?", "Warning",
Messages.getQuestionIcon()) != Messages.OK) {
return;
}
JDOMUtil.writeDocument(new Document(element), filePath, SystemProperties.getLineSeparator());
JDOMUtil.writeParent(element, file, "\n");
}
catch (IOException e1) {
LOG.error(e1);
@@ -40,7 +40,10 @@ public abstract class CodeStyleSchemesImpl extends CodeStyleSchemes {
mySchemeManager = schemeManagerFactory.create(CODE_STYLES_DIR_PATH, new LazySchemeProcessor<CodeStyleScheme, CodeStyleSchemeImpl>() {
@NotNull
@Override
public CodeStyleSchemeImpl createScheme(@NotNull SchemeDataHolder<? super CodeStyleSchemeImpl> dataHolder, @NotNull String name, @NotNull Function<String, String> attributeProvider) {
public CodeStyleSchemeImpl createScheme(@NotNull SchemeDataHolder<? super CodeStyleSchemeImpl> dataHolder,
@NotNull String name,
@NotNull Function<String, String> attributeProvider,
boolean isBundled) {
return new CodeStyleSchemeImpl(attributeProvider.apply("name"), attributeProvider.apply("parent"), dataHolder);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -90,11 +90,6 @@ public class RefactoringQuickListPopupAction extends QuickSwitchSchemeAction {
}
}
@Override
protected boolean isEnabled() {
return true;
}
@Override
public void update(@NotNull AnActionEvent e) {
super.update(e);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -93,5 +93,7 @@ public abstract class QuickSwitchSchemeAction extends AnAction implements DumbAw
e.getPresentation().setEnabled(e.getData(CommonDataKeys.PROJECT) != null && isEnabled());
}
protected abstract boolean isEnabled();
protected boolean isEnabled() {
return true;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -42,10 +42,6 @@ public class QuickChangeSchemesAction extends QuickSwitchSchemeAction implements
FeatureUsageTracker.getInstance().triggerFeatureUsed("ui.scheme.quickswitch");
}
protected boolean isEnabled() {
return true;
}
private static DefaultActionGroup getGroup() {
return (DefaultActionGroup)ActionManager.getInstance().getAction(IdeActions.GROUP_CHANGE_SCHEME);
}
@@ -35,15 +35,10 @@ import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packageDependencies.ui.TreeExpansionMonitor;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.InsertPathAction;
import com.intellij.ui.JBDefaultTreeCellRenderer;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.TreeUIHelper;
import com.intellij.ui.*;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.ImageLoader;
import com.intellij.util.ObjectUtils;
@@ -57,7 +52,10 @@ import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -538,8 +536,8 @@ public class CustomizableActionsPanel {
if (StringUtil.isNotEmpty(path)) {
Image image = null;
try {
image = ImageLoader.loadFromStream(VfsUtilCore.convertToURL(VfsUtil.pathToUrl(path.replace(File.separatorChar,
'/'))).openStream());
image = ImageLoader.loadFromStream(VfsUtilCore.convertToURL(VfsUtilCore.pathToUrl(path.replace(File.separatorChar,
'/'))).openStream());
}
catch (IOException e) {
LOG.debug(e);
@@ -0,0 +1,60 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* 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.intellij.internal.statistic;
import com.intellij.internal.statistic.beans.GroupDescriptor;
import com.intellij.internal.statistic.beans.UsageDescriptor;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import org.jdesktop.swingx.util.OS;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.Set;
/**
* @author tav
*/
public class ScaleInfoUsageCollector extends UsagesCollector {
@NotNull
@Override
public Set<UsageDescriptor> getUsages() throws CollectUsagesException {
float scale = JBUI.SYSTEM_DEF_SCALE;
if (OS.isMacOSX()) {
scale = UIUtil.isRetina() ? 2.0f : 1.0f;
} else {
int scaleBase = (int)Math.floor(scale);
float scaleFract = scale - scaleBase;
if (scaleFract == 0.0f) scaleFract = 0.0f; // count integer scale on a precise match only
else if (scaleFract < 0.375f) scaleFract = 0.25f;
else if (scaleFract < 0.625f) scaleFract = 0.5f;
else scaleFract = 0.75f;
scale = scaleBase + scaleFract;
}
String os = OS.isWindows() ? "Windows" : OS.isLinux() ? "Linux" : OS.isMacOSX() ? "Mac" : "Unknown OS";
return Collections.singleton(new UsageDescriptor(os + " screen scale " + scale, 1));
}
@NotNull
@Override
public GroupDescriptor getGroupId() {
return GroupDescriptor.create("user.jdk");
}
}
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.actionSystem.ex;
import com.intellij.configurationStore.SerializableScheme;
import com.intellij.openapi.options.ExternalizableSchemeAdapter;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
@@ -26,13 +27,13 @@ import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
public class QuickList extends ExternalizableSchemeAdapter {
public class QuickList extends ExternalizableSchemeAdapter implements SerializableScheme {
public static final String QUICK_LIST_PREFIX = "QuickList.";
public static final String SEPARATOR_ID = QUICK_LIST_PREFIX + "$Separator$";
private static final String ID_TAG = "id";
private static final String ACTION_TAG = "action";
private static final String DISPLAY_NAME_TAG = "display";
static final String DISPLAY_NAME_TAG = "display";
private static final String DESCRIPTION_TAG = "description";
private String myDescription;
@@ -95,7 +96,7 @@ public class QuickList extends ExternalizableSchemeAdapter {
return QUICK_LIST_PREFIX + getName();
}
public void writeExternal(@NotNull Element groupElement) {
private void writeExternal(@NotNull Element groupElement) {
groupElement.setAttribute(DISPLAY_NAME_TAG, getName());
if (myDescription != null) {
groupElement.setAttribute(DESCRIPTION_TAG, myDescription);
@@ -116,4 +117,12 @@ public class QuickList extends ExternalizableSchemeAdapter {
myActionIds[i] = actionElements.get(i).getAttributeValue(ID_TAG);
}
}
@NotNull
@Override
public Element writeScheme() {
Element element = new Element("list");
writeExternal(element);
return element;
}
}
@@ -1,172 +0,0 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* 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.intellij.openapi.actionSystem.ex;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.actions.QuickSwitchSchemeAction;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.impl.BundledQuickListsProvider;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ExportableApplicationComponent;
import com.intellij.openapi.options.NonLazySchemeProcessor;
import com.intellij.openapi.options.SchemeManager;
import com.intellij.openapi.options.SchemeManagerFactory;
import com.intellij.openapi.project.Project;
import gnu.trove.THashSet;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.Set;
public class QuickListsManager implements ExportableApplicationComponent {
private static final String LIST_TAG = "list";
private final ActionManager myActionManager;
private final SchemeManager<QuickList> mySchemeManager;
public QuickListsManager(@NotNull ActionManager actionManager, @NotNull SchemeManagerFactory schemeManagerFactory) {
myActionManager = actionManager;
mySchemeManager = schemeManagerFactory.create("quicklists", new NonLazySchemeProcessor<QuickList, QuickList>() {
@NotNull
@Override
public QuickList readScheme(@NotNull Element element, boolean duringLoad) {
return createItem(element);
}
@NotNull
@Override
public Element writeScheme(@NotNull QuickList scheme) {
Element element = new Element(LIST_TAG);
scheme.writeExternal(element);
return element;
}
});
}
@NotNull
public static QuickListsManager getInstance() {
return ApplicationManager.getApplication().getComponent(QuickListsManager.class);
}
@Override
@NotNull
public File[] getExportFiles() {
return new File[]{mySchemeManager.getRootDirectory()};
}
@NotNull
@Override
public String getPresentableName() {
return IdeBundle.message("quick.lists.presentable.name");
}
@NotNull
private static QuickList createItem(@NotNull Element element) {
QuickList item = new QuickList();
item.readExternal(element);
return item;
}
@Override
@NotNull
public String getComponentName() {
return "QuickListsManager";
}
@Override
public void initComponent() {
for (BundledQuickListsProvider provider : BundledQuickListsProvider.EP_NAME.getExtensions()) {
for (final String path : provider.getBundledListsRelativePaths()) {
mySchemeManager.loadBundledScheme(path, provider, QuickListsManager::createItem);
}
}
mySchemeManager.loadSchemes();
registerActions();
}
@Override
public void disposeComponent() {
}
@NotNull
public SchemeManager<QuickList> getSchemeManager() {
return mySchemeManager;
}
@NotNull
public QuickList[] getAllQuickLists() {
Collection<QuickList> lists = mySchemeManager.getAllSchemes();
return lists.toArray(new QuickList[lists.size()]);
}
private void registerActions() {
// to prevent exception if 2 or more targets have the same name
Set<String> registeredIds = new THashSet<>();
for (QuickList list : mySchemeManager.getAllSchemes()) {
String actionId = list.getActionId();
if (registeredIds.add(actionId)) {
myActionManager.registerAction(actionId, new InvokeQuickListAction(list));
}
}
}
private void unregisterActions() {
for (String oldId : myActionManager.getActionIds(QuickList.QUICK_LIST_PREFIX)) {
myActionManager.unregisterAction(oldId);
}
}
public void setQuickLists(@NotNull List<QuickList> quickLists) {
unregisterActions();
mySchemeManager.setSchemes(quickLists);
registerActions();
}
private static class InvokeQuickListAction extends QuickSwitchSchemeAction {
private final QuickList myQuickList;
public InvokeQuickListAction(@NotNull QuickList quickList) {
myQuickList = quickList;
myActionPlace = ActionPlaces.ACTION_PLACE_QUICK_LIST_POPUP_ACTION;
getTemplatePresentation().setDescription(myQuickList.getDescription());
getTemplatePresentation().setText(myQuickList.getName(), false);
}
@Override
protected void fillActions(Project project, @NotNull DefaultActionGroup group, @NotNull DataContext dataContext) {
ActionManager actionManager = ActionManager.getInstance();
for (String actionId : myQuickList.getActionIds()) {
if (QuickList.SEPARATOR_ID.equals(actionId)) {
group.addSeparator();
}
else {
AnAction action = actionManager.getAction(actionId);
if (action != null) {
group.add(action);
}
}
}
}
@Override
protected boolean isEnabled() {
return true;
}
}
}
@@ -0,0 +1,132 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* 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.intellij.openapi.actionSystem.ex
import com.intellij.configurationStore.LazySchemeProcessor
import com.intellij.configurationStore.SchemeDataHolder
import com.intellij.ide.IdeBundle
import com.intellij.ide.actions.QuickSwitchSchemeAction
import com.intellij.openapi.actionSystem.ActionManager
import com.intellij.openapi.actionSystem.ActionPlaces
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.actionSystem.DefaultActionGroup
import com.intellij.openapi.actionSystem.impl.BundledQuickListsProvider
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.ExportableApplicationComponent
import com.intellij.openapi.options.SchemeManager
import com.intellij.openapi.options.SchemeManagerFactory
import com.intellij.openapi.project.Project
import gnu.trove.THashSet
import java.util.function.Function
class QuickListsManager(private val myActionManager: ActionManager, schemeManagerFactory: SchemeManagerFactory) : ExportableApplicationComponent {
private val mySchemeManager: SchemeManager<QuickList>
init {
mySchemeManager = schemeManagerFactory.create("quicklists",
object : LazySchemeProcessor<QuickList, QuickList>(QuickList.DISPLAY_NAME_TAG) {
override fun createScheme(dataHolder: SchemeDataHolder<QuickList>,
name: String,
attributeProvider: Function<String, String?>,
isBundled: Boolean): QuickList {
val item = QuickList()
item.readExternal(dataHolder.read())
dataHolder.updateDigest(item)
return item
}
})
}
companion object {
@JvmStatic
val instance: QuickListsManager
get() = ApplicationManager.getApplication().getComponent(QuickListsManager::class.java)
}
override fun getExportFiles() = arrayOf(mySchemeManager.rootDirectory)
override fun getPresentableName() = IdeBundle.message("quick.lists.presentable.name")!!
override fun getComponentName() = "QuickListsManager"
override fun initComponent() {
for (provider in BundledQuickListsProvider.EP_NAME.extensions) {
for (path in provider.bundledListsRelativePaths) {
mySchemeManager.loadBundledScheme(path, provider)
}
}
mySchemeManager.loadSchemes()
registerActions()
}
override fun disposeComponent() {
}
val schemeManager: SchemeManager<QuickList>
get() = mySchemeManager
val allQuickLists: Array<QuickList>
get() {
return mySchemeManager.allSchemes.toTypedArray()
}
private fun registerActions() {
// to prevent exception if 2 or more targets have the same name
val registeredIds = THashSet<String>()
for (scheme in mySchemeManager.allSchemes) {
val actionId = scheme.actionId
if (registeredIds.add(actionId)) {
myActionManager.registerAction(actionId, InvokeQuickListAction(scheme))
}
}
}
private fun unregisterActions() {
for (oldId in myActionManager.getActionIds(QuickList.QUICK_LIST_PREFIX)) {
myActionManager.unregisterAction(oldId)
}
}
// used by external plugin
fun setQuickLists(quickLists: List<QuickList>) {
unregisterActions()
mySchemeManager.setSchemes(quickLists)
registerActions()
}
}
private class InvokeQuickListAction(private val myQuickList: QuickList) : QuickSwitchSchemeAction() {
init {
myActionPlace = ActionPlaces.ACTION_PLACE_QUICK_LIST_POPUP_ACTION
templatePresentation.description = myQuickList.description
templatePresentation.setText(myQuickList.name, false)
}
override fun fillActions(project: Project, group: DefaultActionGroup, dataContext: DataContext) {
val actionManager = ActionManager.getInstance()
for (actionId in myQuickList.actionIds) {
if (QuickList.SEPARATOR_ID == actionId) {
group.addSeparator()
}
else {
val action = actionManager.getAction(actionId)
if (action != null) {
group.add(action)
}
}
}
}
}
@@ -1,30 +0,0 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* 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.intellij.openapi.editor.colors.impl;
import com.intellij.openapi.extensions.AbstractExtensionPointBean;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.util.xmlb.annotations.Attribute;
/**
* @author yole
*/
public class BundledColorSchemeEP extends AbstractExtensionPointBean {
public static final ExtensionPointName<BundledColorSchemeEP> EP_NAME = ExtensionPointName.create("com.intellij.bundledColorScheme");
@Attribute("path")
public String path;
}
@@ -16,6 +16,10 @@
package com.intellij.openapi.editor.colors.impl;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.configurationStore.BundledSchemeEP;
import com.intellij.configurationStore.LazySchemeProcessor;
import com.intellij.configurationStore.SchemeDataHolder;
import com.intellij.configurationStore.SchemeExtensionProvider;
import com.intellij.ide.WelcomeWizardUtil;
import com.intellij.ide.ui.LafManager;
import com.intellij.openapi.application.ApplicationManager;
@@ -29,7 +33,7 @@ import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.colors.ex.DefaultColorSchemesManager;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.options.BaseSchemeProcessor;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.options.SchemeManager;
import com.intellij.openapi.options.SchemeManagerFactory;
import com.intellij.openapi.options.SchemeState;
@@ -41,7 +45,6 @@ import com.intellij.util.JdomKt;
import com.intellij.util.io.URLUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.xmlb.annotations.OptionTag;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -51,6 +54,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;
@State(
name = "EditorColorsManagerImpl",
@@ -59,8 +63,8 @@ import java.util.List;
)
public class EditorColorsManagerImpl extends EditorColorsManager implements PersistentStateComponent<EditorColorsManagerImpl.State> {
private static final Logger LOG = Logger.getInstance(EditorColorsManagerImpl.class);
private static final ExtensionPointName<BundledSchemeEP> BUNDLED_EP_NAME = ExtensionPointName.create("com.intellij.bundledColorScheme");
@NonNls private static final String SCHEME_NODE_NAME = "scheme";
private static final String DEFAULT_NAME = "Default";
private final ComponentTreeEventDispatcher<EditorColorsListener> myTreeDispatcher = ComponentTreeEventDispatcher.create(EditorColorsListener.class);
@@ -74,23 +78,20 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers
public EditorColorsManagerImpl(@NotNull DefaultColorSchemesManager defaultColorSchemeManager, @NotNull SchemeManagerFactory schemeManagerFactory) {
myDefaultColorSchemeManager = defaultColorSchemeManager;
mySchemeManager = schemeManagerFactory.create(FILE_SPEC, new BaseSchemeProcessor<EditorColorsScheme, EditorColorsSchemeImpl>() {
class EditorColorSchemeProcessor extends LazySchemeProcessor<EditorColorsScheme, EditorColorsSchemeImpl> implements SchemeExtensionProvider {
@NotNull
@Override
public EditorColorsSchemeImpl readScheme(@NotNull Element element, boolean duringLoad) {
EditorColorsSchemeImpl scheme = new EditorColorsSchemeImpl(null);
scheme.readExternal(element);
public EditorColorsSchemeImpl createScheme(@NotNull SchemeDataHolder<? super EditorColorsSchemeImpl> dataHolder,
@NotNull String name,
@NotNull Function<String, String> attributeProvider,
boolean isBundled) {
EditorColorsSchemeImpl scheme = isBundled ? new BundledScheme() : new EditorColorsSchemeImpl(null);
// todo be lazy
scheme.readExternal(dataHolder.read());
dataHolder.updateDigest(scheme);
return scheme;
}
@NotNull
@Override
public Element writeScheme(@NotNull final EditorColorsSchemeImpl scheme) {
Element root = new Element(SCHEME_NODE_NAME);
scheme.writeExternal(root);
return root;
}
@NotNull
@Override
public SchemeState getState(@NotNull EditorColorsScheme scheme) {
@@ -114,12 +115,8 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers
public String getSchemeExtension() {
return ".icls";
}
@Override
public boolean isUpgradeNeeded() {
return true;
}
});
}
mySchemeManager = schemeManagerFactory.create(FILE_SPEC, new EditorColorSchemeProcessor());
initDefaultSchemes();
loadBundledSchemes();
@@ -155,8 +152,8 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers
private void loadBundledSchemes() {
if (!isUnitTestOrHeadlessMode()) {
for (BundledColorSchemeEP ep : BundledColorSchemeEP.EP_NAME.getExtensions()) {
mySchemeManager.loadBundledScheme(ep.path + ".xml", ep, BundledScheme::new);
for (BundledSchemeEP ep : BUNDLED_EP_NAME.getExtensions()) {
mySchemeManager.loadBundledScheme(ep.getPath() + ".xml", ep);
}
}
}
@@ -197,10 +194,8 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers
}
static class BundledScheme extends EditorColorsSchemeImpl implements ReadOnlyColorsScheme {
public BundledScheme(@NotNull Element element) {
public BundledScheme() {
super(null);
readExternal(element);
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,6 @@ import com.intellij.openapi.options.ConfigurableUi;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.ui.Splitter;
import com.intellij.ui.DocumentAdapter;
import com.intellij.util.PairProcessor;
import com.intellij.util.ui.ListItemEditor;
import com.intellij.util.ui.ListModelEditor;
import org.jetbrains.annotations.NotNull;
@@ -424,12 +424,9 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
@Override
public void initToolWindow(@NotNull ToolWindowEP bean) {
JLabel label = new JLabel("Initializing...", SwingConstants.CENTER);
label.setOpaque(true);
final Color treeBg = UIManager.getColor("Tree.background");
label.setBackground(ColorUtil.toAlpha(treeBg, 180));
final Color treeFg = UIUtil.getTreeForeground();
label.setForeground(ColorUtil.toAlpha(treeFg, 180));
WindowInfoImpl before = myLayout.getInfo(bean.id, false);
boolean visible = before != null && before.isVisible();
JLabel label = createInitializingLabel();
ToolWindowAnchor toolWindowAnchor = ToolWindowAnchor.fromText(bean.anchor);
final ToolWindowFactory factory = bean.getToolWindowFactory();
final ToolWindowImpl toolWindow =
@@ -461,7 +458,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
toolWindow.ensureContentInitialized();
activation.setDone();
};
if (ApplicationManager.getApplication().isUnitTestMode()) {
if (visible || ApplicationManager.getApplication().isUnitTestMode()) {
runnable.run();
}
else {
@@ -469,6 +466,17 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
}
}
@NotNull
private static JLabel createInitializingLabel() {
JLabel label = new JLabel("Initializing...", SwingConstants.CENTER);
label.setOpaque(true);
final Color treeBg = UIManager.getColor("Tree.background");
label.setBackground(ColorUtil.toAlpha(treeBg, 180));
final Color treeFg = UIUtil.getTreeForeground();
label.setForeground(ColorUtil.toAlpha(treeFg, 180));
return label;
}
@Override
public void projectClosed() {
final String[] ids = getToolWindowIds();
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -131,8 +131,10 @@ public class ComboboxEditorTextField extends EditorTextField {
// TODO:
if (UIUtil.isUnderDarcula() || UIUtil.isUnderIntelliJLaF() || (SystemInfo.isMac && UIUtil.isUnderAquaLookAndFeel())) {
IdeFocusManager.getInstance(getProject()).doWhenFocusSettlesDown(() -> {
final Container parent1 = getParent();
if (parent1 != null) parent1.repaint();
JComboBox comboBox = UIUtil.getParentOfType(JComboBox.class, this);
if (comboBox != null) {
comboBox.repaint();
}
});
}
}
@@ -687,7 +687,7 @@ confirm.set.look.and.feel=Change &theme
error.cannot.set.look.and.feel=<html><body>Cannot set {0} theme:<br>{1}</body></html>
warning.problem.laf.1=<html><body>GTK+ theme is known to be problematic on a JDK prior to 1.6 b12.<br>Please choose another theme, or upgrade your JDK. <a href="http://bugs.sun.com/view_bug.do?bug_id=6624717">More info...</a></body></html>
error.adding.action.without.icon.to.toolbar=You are adding an action without icon to the toolbar. The default icon will be added to this action.
title.unable.to.add.action.without.icon.to.toolbar=Unable to add action without icon to the toolbar
title.unable.to.add.action.without.icon.to.toolbar=Unable to Add Action Without Icon to the Toolbar
error.please.specify.new.name.for.schema=Please, specify new name for scheme ''{0}''.
title.browse.icon=Browse Icon
prompt.browse.icon.for.selected.action=Browse icon for selected action (*.png)
@@ -141,7 +141,7 @@
<extensionPoint name="customFileDropHandler" area="IDEA_PROJECT" interface="com.intellij.openapi.editor.CustomFileDropHandler"/>
<extensionPoint name="additionalTextAttributes" beanClass="com.intellij.openapi.editor.colors.impl.AdditionalTextAttributesEP" />
<extensionPoint name="bundledColorScheme" beanClass="com.intellij.openapi.editor.colors.impl.BundledColorSchemeEP"/>
<extensionPoint name="bundledColorScheme" beanClass="com.intellij.configurationStore.BundledSchemeEP"/>
<extensionPoint name="bundledQuickListsProvider" interface="com.intellij.openapi.actionSystem.impl.BundledQuickListsProvider"/>
<extensionPoint name="bundledKeymapProvider" interface="com.intellij.openapi.keymap.impl.BundledKeymapProvider"/>
@@ -272,5 +272,6 @@
<extensionPoint name="credentialStore" interface="com.intellij.credentialStore.CredentialStoreFactory"/>
<extensionPoint name="supportColorBlindness" interface="com.intellij.ide.ui.ColorBlindnessSupport"/>
<extensionPoint name="bundledInspectionProfile" beanClass="com.intellij.configurationStore.BundledSchemeEP"/>
</extensionPoints>
</idea-plugin>
@@ -353,6 +353,7 @@
<statistics.usagesCollector implementation="com.intellij.internal.statistic.UiInfoUsageCollector"/>
<statistics.usagesCollector implementation="com.intellij.internal.statistic.JdkInfoUsageCollector"/>
<statistics.usagesCollector implementation="com.intellij.internal.statistic.BuildNumberUsageCollector"/>
<statistics.usagesCollector implementation="com.intellij.internal.statistic.ScaleInfoUsageCollector"/>
<applicationConfigurable parentId="preferences.general" instance="com.intellij.internal.statistic.configurable.StatisticsConfigurable" id="usage.statistics"
displayName="Usage Statistics"/>
@@ -15,22 +15,25 @@
*/
package com.intellij.configurationStore
import com.intellij.openapi.extensions.AbstractExtensionPointBean
import com.intellij.openapi.options.*
import com.intellij.openapi.project.Project
import com.intellij.project.isDirectoryBased
import com.intellij.util.isEmpty
import com.intellij.util.xmlb.annotations.Attribute
import org.jdom.Element
import java.io.OutputStream
import java.security.MessageDigest
import java.util.concurrent.atomic.AtomicReference
import java.util.function.Function
interface SchemeDataHolder<in MUTABLE_SCHEME : Scheme> {
interface SchemeDataHolder<in T : Scheme> {
/**
* You should call updateDigest() after read on init.
*/
fun read(): Element
fun updateDigest(scheme: MUTABLE_SCHEME)
fun updateDigest(scheme: T)
fun updateDigest(data: Element)
}
@@ -45,22 +48,20 @@ interface SerializableScheme {
*/
interface SchemeExtensionProvider {
/**
* @return The scheme file extension **with e leading dot**, for example ".ext".
* @return The scheme file extension **with a leading dot**, for example ".ext".
*/
val schemeExtension: String
/**
* @return True if the upgrade from the old default .xml extension is needed.
*/
val isUpgradeNeeded: Boolean
}
abstract class LazySchemeProcessor<SCHEME : Scheme, MUTABLE_SCHEME : SCHEME> : SchemeProcessor<SCHEME, MUTABLE_SCHEME>() {
abstract class LazySchemeProcessor<SCHEME : Scheme, MUTABLE_SCHEME : SCHEME>(private val nameAttribute: String = "name") : SchemeProcessor<SCHEME, MUTABLE_SCHEME>() {
open fun getName(attributeProvider: Function<String, String?>): String {
return attributeProvider.apply("name") ?: throw IllegalStateException("name is missed in the scheme data")
return attributeProvider.apply(nameAttribute) ?: throw IllegalStateException("name is missed in the scheme data")
}
abstract fun createScheme(dataHolder: SchemeDataHolder<MUTABLE_SCHEME>, name: String, attributeProvider: Function<String, String?>): MUTABLE_SCHEME
abstract fun createScheme(dataHolder: SchemeDataHolder<MUTABLE_SCHEME>,
name: String,
attributeProvider: Function<String, String?>,
isBundled: Boolean = false): MUTABLE_SCHEME
override final fun writeScheme(scheme: MUTABLE_SCHEME) = (scheme as SerializableScheme).writeScheme()
@@ -104,6 +105,15 @@ abstract class SchemeWrapper<out T : Scheme>(name: String) : ExternalizableSchem
}
}
abstract class LazySchemeWrapper<T : Scheme>(name: String, dataHolder: SchemeDataHolder<SchemeWrapper<T>>, protected val writer: (scheme: T) -> Element) : SchemeWrapper<T>(name) {
protected val dataHolder = AtomicReference(dataHolder)
override final fun writeScheme(): Element {
val dataHolder = dataHolder.get()
return if (dataHolder == null) writer(scheme) else dataHolder.read()
}
}
class InitializedSchemeWrapper<out T : Scheme>(scheme: T, private val writer: (scheme: T) -> Element) : SchemeWrapper<T>(scheme.name) {
override val lazyScheme = lazyOf(scheme)
@@ -128,4 +138,9 @@ fun wrapState(element: Element, project: Project): Element {
val wrapper = Element("state")
wrapper.addContent(element)
return wrapper
}
class BundledSchemeEP : AbstractExtensionPointBean() {
@Attribute("path")
var path: String? = null
}
@@ -31,10 +31,7 @@ abstract class ExternalizableSchemeAdapter : ExternalizableScheme {
override fun toString() = name
}
abstract class BaseSchemeProcessor<SCHEME : Scheme, MUTABLE_SCHEME : SCHEME> : NonLazySchemeProcessor<SCHEME, MUTABLE_SCHEME>(), SchemeExtensionProvider {
override val isUpgradeNeeded = false
override val schemeExtension = ".xml"
abstract class BaseSchemeProcessor<SCHEME : Scheme, MUTABLE_SCHEME : SCHEME> : NonLazySchemeProcessor<SCHEME, MUTABLE_SCHEME>() {
}
abstract class NonLazySchemeProcessor<SCHEME : Scheme, MUTABLE_SCHEME : SCHEME> : SchemeProcessor<SCHEME, MUTABLE_SCHEME>() {
@@ -16,8 +16,6 @@
package com.intellij.openapi.options;
import com.intellij.openapi.util.Condition;
import com.intellij.util.ThrowableConvertor;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -98,9 +96,11 @@ public abstract class SchemeManager<T extends Scheme> {
public abstract File getRootDirectory();
/**
* Must be called before {@link #loadSchemes}
* Must be called before {@link #loadSchemes}.
*
* Scheme manager processor must be LazySchemeProcessor
*/
public void loadBundledScheme(@NotNull String resourceName, @NotNull Object requestor, @NotNull ThrowableConvertor<Element, T, Throwable> convertor) {
public void loadBundledScheme(@NotNull String resourceName, @NotNull Object requestor) {
}
public final void setSchemes(@NotNull List<T> newSchemes) {
@@ -277,6 +277,7 @@ public class AllIcons {
public static final Icon KillProcess = IconLoader.getIcon("/debugger/killProcess.png"); // 16x16
public static final Icon MuteBreakpoints = IconLoader.getIcon("/debugger/muteBreakpoints.png"); // 16x16
public static final Icon NewWatch = IconLoader.getIcon("/debugger/newWatch.png"); // 16x16
public static final Icon Question_badge = IconLoader.getIcon("/debugger/question_badge.png"); // 6x9
public static final Icon RestoreLayout = IconLoader.getIcon("/debugger/restoreLayout.png"); // 16x16
public static final Icon ShowCurrentFrame = IconLoader.getIcon("/debugger/showCurrentFrame.png"); // 16x16
public static final Icon SmartStepInto = IconLoader.getIcon("/debugger/smartStepInto.png"); // 16x16
@@ -44,6 +44,10 @@ public abstract class NotNullLazyValue<T> {
return result;
}
public boolean isComputed() {
return myValue != null;
}
@NotNull
public static <T> NotNullLazyValue<T> createConstantValue(@NotNull final T value) {
return new NotNullLazyValue<T>() {
@@ -0,0 +1,83 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* 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.intellij.util.ui;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.util.ui.accessibility.ScreenReader;
import org.jetbrains.annotations.NonNls;
import javax.swing.*;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.StyleSheet;
import java.awt.*;
import static com.intellij.util.ui.UIUtil.getLabelFont;
import static com.intellij.util.ui.UIUtil.isUnderDarcula;
/**
* @author Dmitry Avdeev
*/
public class HTMLEditorKitProvider {
private static final Logger LOG = Logger.getInstance(HTMLEditorKitProvider.class);
private static final StyleSheet DEFAULT_HTML_KIT_CSS;
static {
blockATKWrapper();
// save the default JRE CSS and ..
HTMLEditorKit kit = new HTMLEditorKit();
DEFAULT_HTML_KIT_CSS = kit.getStyleSheet();
// .. erase global ref to this CSS so no one can alter it
kit.setStyleSheet(null);
}
private static void blockATKWrapper() {
/*
* The method should be called before java.awt.Toolkit.initAssistiveTechnologies()
* which is called from Toolkit.getDefaultToolkit().
*/
if (!(SystemInfo.isLinux && Registry.is("linux.jdk.accessibility.atkwrapper.block"))) return;
if (ScreenReader.isEnabled(ScreenReader.ATK_WRAPPER)) {
// Replace AtkWrapper with a dummy Object. It'll be instantiated & GC'ed right away, a NOP.
System.setProperty("javax.accessibility.assistive_technologies", "java.lang.Object");
LOG.info(ScreenReader.ATK_WRAPPER + " is blocked, see IDEA-149219");
}
}
public static HTMLEditorKit getHTMLEditorKit(boolean noGapsBetweenParagraphs) {
Font font = getLabelFont();
@NonNls String family = !SystemInfo.isWindows && font != null ? font.getFamily() : "Tahoma";
int size = font != null ? font.getSize() : JBUI.scale(11);
String customCss = String.format("body, div, p { font-family: %s; font-size: %s; }", family, size);
if (noGapsBetweenParagraphs) {
customCss += " p { margin-top: 0; }";
}
final StyleSheet style = new StyleSheet();
style.addStyleSheet(isUnderDarcula() ? (StyleSheet)UIManager.getDefaults().get("StyledEditorKit.JBDefaultStyle") : DEFAULT_HTML_KIT_CSS);
style.addRule(customCss);
return new HTMLEditorKit() {
@Override
public StyleSheet getStyleSheet() {
return style;
}
};
}
}
@@ -37,23 +37,24 @@ import java.awt.*;
public class JBUI {
private static final Logger LOG = Logger.getInstance("#com.intellij.util.ui.JBUI");
private static float scaleFactor = 1.0f;
/**
* A default system scale factor.
*/
public static final float SYSTEM_DEF_SCALE = getSystemDefScale();
private static float scaleFactor;
static {
calculateScaleFactor();
setScaleFactor(SYSTEM_DEF_SCALE);
}
private static void calculateScaleFactor() {
private static float getSystemDefScale() {
if (SystemInfo.isMac) {
LOG.info("UI scale factor: 1.0");
scaleFactor = 1.0f;
return;
return 1.0f;
}
if (SystemProperties.has("hidpi") && !SystemProperties.is("hidpi")) {
LOG.info("UI scale factor: 1.0");
scaleFactor = 1.0f;
return;
return 1.0f;
}
UIUtil.initSystemFontData();
@@ -65,11 +66,13 @@ public class JBUI {
} else {
size = Fonts.label().getSize();
}
setScaleFactor(size/UIUtil.DEF_SYSTEM_FONT_SIZE);
return size / UIUtil.DEF_SYSTEM_FONT_SIZE;
}
public static void setScaleFactor(float scale) {
if (SystemProperties.has("hidpi") && !SystemProperties.is("hidpi")) {
scaleFactor = 1.0f;
LOG.info("UI scale factor: 1.0");
return;
}
@@ -30,7 +30,6 @@ import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.JBIterable;
import com.intellij.util.containers.JBTreeTraverser;
import com.intellij.util.containers.WeakHashMap;
import com.intellij.util.ui.accessibility.ScreenReader;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -93,31 +92,6 @@ public class UIUtil {
public static final String BORDER_LINE = "<hr size=1 noshade>";
private static final StyleSheet DEFAULT_HTML_KIT_CSS;
static {
blockATKWrapper();
// save the default JRE CSS and ..
HTMLEditorKit kit = new HTMLEditorKit();
DEFAULT_HTML_KIT_CSS = kit.getStyleSheet();
// .. erase global ref to this CSS so no one can alter it
kit.setStyleSheet(null);
}
private static void blockATKWrapper() {
/*
* The method should be called before java.awt.Toolkit.initAssistiveTechnologies()
* which is called from Toolkit.getDefaultToolkit().
*/
if (!(SystemInfo.isLinux && Registry.is("linux.jdk.accessibility.atkwrapper.block"))) return;
if (ScreenReader.isEnabled(ScreenReader.ATK_WRAPPER)) {
// Replace AtkWrapper with a dummy Object. It'll be instantiated & GC'ed right away, a NOP.
System.setProperty("javax.accessibility.assistive_technologies", "java.lang.Object");
LOG.info(ScreenReader.ATK_WRAPPER + " is blocked, see IDEA-149219");
}
}
public static int getMultiClickInterval() {
Object property = Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval");
if (property instanceof Integer) {
@@ -2335,25 +2309,7 @@ public class UIUtil {
}
public static HTMLEditorKit getHTMLEditorKit(boolean noGapsBetweenParagraphs) {
Font font = getLabelFont();
@NonNls String family = !SystemInfo.isWindows && font != null ? font.getFamily() : "Tahoma";
int size = font != null ? font.getSize() : JBUI.scale(11);
String customCss = String.format("body, div, p { font-family: %s; font-size: %s; }", family, size);
if (noGapsBetweenParagraphs) {
customCss += " p { margin-top: 0; }";
}
final StyleSheet style = new StyleSheet();
style.addStyleSheet(isUnderDarcula() ? (StyleSheet)UIManager.getDefaults().get("StyledEditorKit.JBDefaultStyle") : DEFAULT_HTML_KIT_CSS);
style.addRule(customCss);
return new HTMLEditorKit() {
@Override
public StyleSheet getStyleSheet() {
return style;
}
};
return HTMLEditorKitProvider.getHTMLEditorKit(noGapsBetweenParagraphs);
}
public static void removeScrollBorder(final Component c) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -65,10 +65,6 @@ public class VcsQuickListPopupAction extends QuickSwitchSchemeAction implements
}
}
protected boolean isEnabled() {
return true;
}
private void fillVcsPopup(@NotNull final Project project,
@NotNull final DefaultActionGroup group,
@Nullable final DataContext dataContext,
@@ -34,9 +34,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.SimpleToolWindowPanel;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Factory;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsBundle;
@@ -97,7 +95,13 @@ public class ChangesViewManager implements ChangesViewI, ProjectComponent, Persi
private JBSplitter mySplitter;
private boolean myDetailsOn;
@NotNull private final MyChangeProcessor myDiffDetails;
@NotNull private final NotNullLazyValue<MyChangeProcessor> myDiffDetails = new NotNullLazyValue<MyChangeProcessor>() {
@NotNull
@Override
protected MyChangeProcessor compute() {
return new MyChangeProcessor(myProject);
}
};
@NotNull private final TreeSelectionListener myTsl;
private Content myContent;
@@ -112,7 +116,6 @@ public class ChangesViewManager implements ChangesViewI, ProjectComponent, Persi
myContentManager = contentManager;
myView = new ChangesListView(project);
myRepaintAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, project);
myDiffDetails = new MyChangeProcessor(myProject);
myTsl = new TreeSelectionListener() {
@Override
public void valueChanged(TreeSelectionEvent e) {
@@ -167,7 +170,6 @@ public class ChangesViewManager implements ChangesViewI, ProjectComponent, Persi
}
public void projectClosed() {
Disposer.dispose(myDiffDetails);
myView.removeTreeSelectionListener(myTsl);
myDisposed = true;
myRepaintAlarm.cancelAllRequests();
@@ -239,17 +241,19 @@ public class ChangesViewManager implements ChangesViewI, ProjectComponent, Persi
private void changeDetails() {
if (!myDetailsOn) {
myDiffDetails.clear();
if (myDiffDetails.isComputed()) {
myDiffDetails.getValue().clear();
if (mySplitter.getSecondComponent() != null) {
setChangeDetailsPanel(null);
if (mySplitter.getSecondComponent() != null) {
setChangeDetailsPanel(null);
}
}
}
else {
myDiffDetails.refresh();
myDiffDetails.getValue().refresh();
if (mySplitter.getSecondComponent() == null) {
setChangeDetailsPanel(myDiffDetails.getComponent());
setChangeDetailsPanel(myDiffDetails.getValue().getComponent());
}
}
}
@@ -528,6 +532,7 @@ public class ChangesViewManager implements ChangesViewI, ProjectComponent, Persi
private class MyChangeProcessor extends CacheChangeProcessor {
public MyChangeProcessor(@NotNull Project project) {
super(project, DiffPlaces.CHANGES_VIEW);
Disposer.register(project, this);
}
@Override
@@ -15,6 +15,7 @@
*/
package com.intellij.xdebugger.impl.breakpoints;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.components.ComponentSerializationUtil;
@@ -29,6 +30,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.Navigatable;
import com.intellij.ui.ColorUtil;
import com.intellij.ui.JBColor;
import com.intellij.ui.LayeredIcon;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters;
import com.intellij.util.xmlb.XmlSerializer;
@@ -43,6 +45,7 @@ import com.intellij.xdebugger.breakpoints.XBreakpointType;
import com.intellij.xdebugger.impl.DebuggerSupport;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.XDebuggerSupport;
import com.intellij.xdebugger.impl.XDebuggerUtilImpl;
import com.intellij.xdebugger.impl.actions.EditBreakpointAction;
import com.intellij.xml.CommonXmlStrings;
import com.intellij.xml.util.XmlStringUtil;
@@ -393,11 +396,19 @@ public class XBreakpointBase<Self extends XBreakpoint<P>, P extends XBreakpointP
protected void updateIcon() {
final Icon icon = calculateSpecialIcon();
myIcon = icon != null ? icon : getType().getEnabledIcon();
setIcon(icon != null ? icon : getType().getEnabledIcon());
}
protected void setIcon(Icon icon) {
myIcon = icon;
if (!XDebuggerUtilImpl.isEmptyExpression(getConditionExpression())) {
LayeredIcon newIcon = new LayeredIcon(2);
newIcon.setIcon(icon, 0);
newIcon.setIcon(AllIcons.Debugger.Question_badge, 1, 10, 6);
myIcon = newIcon;
}
else {
myIcon = icon;
}
}
@Nullable
@@ -293,12 +293,11 @@ public class XLineBreakpointImpl<P extends XBreakpointProperties> extends XBreak
@Override
protected void updateIcon() {
final Icon icon = calculateSpecialIcon();
if (icon != null) {
setIcon(icon);
return;
Icon icon = calculateSpecialIcon();
if (icon == null) {
icon = isTemporary() ? myType.getTemporaryIcon() : myType.getEnabledIcon();
}
setIcon(isTemporary() ? myType.getTemporaryIcon() : myType.getEnabledIcon());
setIcon(icon);
}
@Override
@@ -38,6 +38,7 @@ import com.intellij.reference.SoftReference;
import com.intellij.ui.ClickListener;
import com.intellij.ui.LayeredIcon;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.components.BorderLayoutPanel;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.XExpression;
import com.intellij.xdebugger.XSourcePosition;
@@ -139,22 +140,33 @@ public abstract class XDebuggerEditorBase {
}
protected JPanel decorate(JComponent component, boolean multiline, boolean showEditor) {
JPanel panel = JBUI.Panels.simplePanel();
BorderLayoutPanel panel = JBUI.Panels.simplePanel();
JPanel factoryPanel = JBUI.Panels.simplePanel();
factoryPanel.add(myChooseFactory, multiline ? BorderLayout.NORTH : BorderLayout.CENTER);
panel.add(factoryPanel, BorderLayout.WEST);
if (!multiline && showEditor) {
ComponentWithBrowseButton<JComponent> componentWithButton =
new ComponentWithBrowseButton<>(component, e -> showCodeFragmentEditor(component, this));
componentWithButton.setButtonIcon(AllIcons.Actions.ShowViewer);
componentWithButton.getButton().setDisabledIcon(IconLoader.getDisabledIcon(AllIcons.Actions.ShowViewer));
panel.add(componentWithButton, BorderLayout.CENTER);
} else {
panel.add(component, BorderLayout.CENTER);
component = addMultilineButton(component);
}
panel.addToCenter(component);
return panel;
}
protected JPanel addMultilineButton(JComponent component) {
ComponentWithBrowseButton<JComponent> componentWithButton =
new ComponentWithBrowseButton<>(component, e -> showCodeFragmentEditor(component, this));
componentWithButton.setButtonIcon(AllIcons.Actions.ShowViewer);
componentWithButton.getButton().setDisabledIcon(IconLoader.getDisabledIcon(AllIcons.Actions.ShowViewer));
return componentWithButton;
}
protected JComponent addChooser(JComponent component) {
BorderLayoutPanel panel = JBUI.Panels.simplePanel(component);
panel.setBackground(component.getBackground());
panel.addToRight(myChooseFactory);
return panel;
}
@@ -345,7 +357,10 @@ public abstract class XDebuggerEditorBase {
protected void doOKAction() {
super.doOKAction();
baseEditor.setExpression(inputComponent.getInputEditor().getExpression());
IdeFocusManager.findInstance().requestFocus(baseEditor.getEditorComponent(), false);
JComponent component = baseEditor.getPreferredFocusedComponent();
if (component != null) {
IdeFocusManager.findInstance().requestFocus(component, false);
}
}
@Nullable
@@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.ui.EditorComboBoxEditor;
import com.intellij.ui.EditorComboBoxRenderer;
import com.intellij.ui.EditorTextField;
import com.intellij.util.ui.UIUtil;
import com.intellij.xdebugger.XExpression;
import com.intellij.xdebugger.XSourcePosition;
@@ -35,6 +36,7 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
/**
* @author nik
@@ -42,7 +44,7 @@ import java.awt.*;
public class XDebuggerExpressionComboBox extends XDebuggerEditorBase {
private final JComponent myComponent;
private final ComboBox<XExpression> myComboBox;
private EditorComboBoxEditor myEditor;
private XDebuggerComboBoxEditor myEditor;
private XExpression myExpression;
public XDebuggerExpressionComboBox(@NotNull Project project, @NotNull XDebuggerEditorsProvider debuggerEditorsProvider, @Nullable @NonNls String historyId,
@@ -56,7 +58,7 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase {
myComboBox.setMinimumSize(minimumSize);
initEditor();
fillComboBox();
myComponent = decorate(myComboBox, false, showEditor);
myComponent = showEditor ? addMultilineButton(myComboBox) : myComboBox;
}
public ComboBox getComboBox() {
@@ -70,11 +72,11 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase {
@Nullable
public Editor getEditor() {
return myEditor.getEditor();
return myEditor.getEditorTextField().getEditor();
}
public JComponent getEditorComponent() {
return myEditor.getEditorComponent();
return myEditor.getEditorTextField();
}
public void setEnabled(boolean enable) {
@@ -92,23 +94,7 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase {
}
private void initEditor() {
myEditor = new EditorComboBoxEditor(getProject(), getEditorsProvider().getFileType()) {
@Override
public void setItem(Object anObject) {
if (anObject == null) {
anObject = XExpressionImpl.EMPTY_EXPRESSION;
}
XExpression expression = (XExpression)anObject;
getEditorComponent().setNewDocumentAndFileType(getFileType(expression), createDocument(expression));
}
@Override
protected void onEditorCreate(EditorEx editor) {
editor.putUserData(DebuggerCopyPastePreprocessor.REMOVE_NEWLINES_ON_PASTE, true);
editor.getColorsScheme().setEditorFontSize(myComboBox.getFont().getSize());
}
};
myEditor.getEditorComponent().setFontInheritedFromLAF(false);
myEditor = new XDebuggerComboBoxEditor();
myComboBox.setEditor(myEditor);
//myEditor.setItem(myExpression);
myComboBox.setRenderer(new EditorComboBoxRenderer(myEditor));
@@ -144,20 +130,76 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase {
@Override
public XExpression getExpression() {
Object document = myEditor.getItem();
if (document instanceof Document) { // sometimes null on Mac
return getEditorsProvider().createExpression(getProject(), (Document)document, myExpression.getLanguage(), myExpression.getMode());
}
return myExpression;
XExpression item = myEditor.getItem();
return item != null ? item : myExpression;
}
@Override
public JComponent getPreferredFocusedComponent() {
return (JComponent)myComboBox.getEditor().getEditorComponent();
return myEditor.getEditorTextField();
}
@Override
public void selectAll() {
myComboBox.getEditor().selectAll();
}
private class XDebuggerComboBoxEditor implements ComboBoxEditor {
private final JComponent myPanel;
private final EditorComboBoxEditor myDelegate;
public XDebuggerComboBoxEditor() {
myDelegate = new EditorComboBoxEditor(getProject(), getEditorsProvider().getFileType()) {
@Override
protected void onEditorCreate(EditorEx editor) {
editor.putUserData(DebuggerCopyPastePreprocessor.REMOVE_NEWLINES_ON_PASTE, true);
editor.getColorsScheme().setEditorFontSize(myComboBox.getFont().getSize());
}
};
myDelegate.getEditorComponent().setFontInheritedFromLAF(false);
myPanel = addChooser(myDelegate.getEditorComponent());
}
public EditorTextField getEditorTextField() {
return myDelegate.getEditorComponent();
}
@Override
public JComponent getEditorComponent() {
return myPanel;
}
@Override
public void setItem(Object anObject) {
if (anObject == null) {
anObject = XExpressionImpl.EMPTY_EXPRESSION;
}
XExpression expression = (XExpression)anObject;
myDelegate.getEditorComponent().setNewDocumentAndFileType(getFileType(expression), createDocument(expression));
}
@Override
public XExpression getItem() {
Object document = myDelegate.getItem();
if (document instanceof Document) { // sometimes null on Mac
return getEditorsProvider().createExpression(getProject(), (Document)document, myExpression.getLanguage(), myExpression.getMode());
}
return null;
}
@Override
public void selectAll() {
myDelegate.selectAll();
}
@Override
public void addActionListener(ActionListener l) {
myDelegate.addActionListener(l);
}
@Override
public void removeActionListener(ActionListener l) {
myDelegate.removeActionListener(l);
}
}
}
@@ -20,6 +20,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.ui.Messages;
import com.intellij.ui.AppUIUtil;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.util.ui.JBUI;
import com.intellij.xdebugger.frame.XValueModifier;
import com.intellij.xdebugger.frame.presentation.XValuePresentation;
import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl;
@@ -28,6 +29,7 @@ import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValuePresentationUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
@@ -39,24 +41,36 @@ public class SetValueInplaceEditor extends XDebuggerTreeInplaceEditor {
private final JPanel myEditorPanel;
private final XValueModifier myModifier;
private final XValueNodeImpl myValueNode;
private final int myNameOffset;
private SetValueInplaceEditor(final XValueNodeImpl node, @NotNull final String nodeName) {
super(node, "setValue");
myValueNode = node;
myModifier = myValueNode.getValueContainer().getModifier();
myEditorPanel = new JPanel();
myEditorPanel.setLayout(new BorderLayout(0, 0));
SimpleColoredComponent nameLabel = new SimpleColoredComponent();
nameLabel.getIpad().right = 0;
nameLabel.getIpad().left = 0;
nameLabel.setIcon(myNode.getIcon());
nameLabel.append(nodeName, XDebuggerUIConstants.VALUE_NAME_ATTRIBUTES);
XValuePresentation presentation = node.getValuePresentation();
if (presentation != null) {
XValuePresentationUtil.appendSeparator(nameLabel, presentation.getSeparator());
}
myEditorPanel.add(nameLabel, BorderLayout.WEST);
myNameOffset = nameLabel.getPreferredSize().width;
myEditorPanel = JBUI.Panels.simplePanel(myExpressionEditor.getComponent());
}
myEditorPanel.add(myExpressionEditor.getComponent(), BorderLayout.CENTER);
@Nullable
@Override
protected Rectangle getEditorBounds() {
Rectangle bounds = super.getEditorBounds();
if (bounds == null) {
return null;
}
bounds.x += myNameOffset;
bounds.width -= myNameOffset;
return bounds;
}
public static void show(final XValueNodeImpl node, @NotNull final String nodeName) {
@@ -97,10 +97,8 @@ public abstract class TreeInplaceEditor implements AWTEventListener {
protected abstract Project getProject();
private static void setInplaceEditorBounds(JComponent component, int x, int y, int width, int height) {
int preferredHeight = component.getPreferredSize().height;
int h = Math.max(height, preferredHeight);
int delta = Math.max(0, h - height) / 2;
component.setBounds(x, y - delta, width, Math.max(height, preferredHeight));
int h = Math.max(height, component.getPreferredSize().height);
component.setBounds(x, y - (h - height) / 2, width, h);
}
public final void show() {
@@ -271,7 +269,7 @@ public abstract class TreeInplaceEditor implements AWTEventListener {
}
@Nullable
private Rectangle getEditorBounds() {
protected Rectangle getEditorBounds() {
final JTree tree = getTree();
Rectangle bounds = tree.getVisibleRect();
Rectangle nodeBounds = tree.getPathBounds(getNodePath());
+7 -14
View File
@@ -50,7 +50,6 @@ import com.maddyhome.idea.copyright.util.FileTypeUtil
import com.maddyhome.idea.copyright.util.NewFileTracker
import org.jdom.Element
import java.util.*
import java.util.concurrent.atomic.AtomicReference
import java.util.function.Function
private const val DEFAULT = "default"
@@ -90,8 +89,9 @@ class CopyrightManager(private val project: Project, schemeManagerFactory: Schem
val schemeManager = schemeManagerFactory.create("copyright", object : LazySchemeProcessor<SchemeWrapper<CopyrightProfile>, SchemeWrapper<CopyrightProfile>>() {
override fun createScheme(dataHolder: SchemeDataHolder<SchemeWrapper<CopyrightProfile>>,
name: String,
attributeProvider: Function<String, String?>): SchemeWrapper<CopyrightProfile> {
return LazySchemeWrapper(name, dataHolder, schemeWriter)
attributeProvider: Function<String, String?>,
isBundled: Boolean): SchemeWrapper<CopyrightProfile> {
return CopyrightLazySchemeWrapper(name, dataHolder, schemeWriter)
}
override fun getState(scheme: SchemeWrapper<CopyrightProfile>) = scheme.schemeState
@@ -253,12 +253,10 @@ private fun wrapScheme(element: Element): Element {
return wrapper
}
private class LazySchemeWrapper(name: String,
dataHolder: SchemeDataHolder<SchemeWrapper<CopyrightProfile>>,
private val writer: (scheme: CopyrightProfile) -> Element,
private val subStateTagName: String = "copyright") : SchemeWrapper<CopyrightProfile>(name) {
private val dataHolder = AtomicReference(dataHolder)
private class CopyrightLazySchemeWrapper(name: String,
dataHolder: SchemeDataHolder<SchemeWrapper<CopyrightProfile>>,
writer: (scheme: CopyrightProfile) -> Element,
private val subStateTagName: String = "copyright") : LazySchemeWrapper<CopyrightProfile>(name, dataHolder, writer) {
override val lazyScheme = lazy {
val scheme = CopyrightProfile()
@Suppress("NAME_SHADOWING")
@@ -272,9 +270,4 @@ private class LazySchemeWrapper(name: String,
dataHolder.updateDigest(writer(scheme))
scheme
}
override fun writeScheme(): Element {
val dataHolder = dataHolder.get()
return if (dataHolder == null) writer(scheme) else dataHolder.read()
}
}
@@ -150,4 +150,20 @@ public class JUnitRerunFailedTestsTest extends LightCodeInsightFixtureTestCase
String name = ((PsiMethod)element).getName();
assertEquals("testFoo", name);
}
public void testLocatorForIgnoredClass() throws Exception {
PsiClass aClass = myFixture.addClass("@org.junit.Ignore" +
"public class TestClass {\n" +
" @org.junit.Test" +
" public void testFoo() throws Exception {}\n" +
"}");
final SMTestProxy testProxy = new SMTestProxy("TestClass", false, "java:test://TestClass.TestClass");
final Project project = getProject();
final GlobalSearchScope searchScope = GlobalSearchScope.projectScope(project);
testProxy.setLocator(JavaTestLocator.INSTANCE);
Location location = testProxy.getLocation(project, searchScope);
assertNotNull(location);
PsiElement element = location.getPsiElement();
assertEquals(aClass, element);
}
}
@@ -17,15 +17,16 @@ package com.intellij.junit4;
import com.intellij.junit3.TestRunnerUtil;
import org.junit.Ignore;
import org.junit.internal.AssumptionViolatedException;
import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
import org.junit.internal.builders.AnnotatedBuilder;
import org.junit.internal.builders.IgnoredBuilder;
import org.junit.internal.builders.JUnit4Builder;
import org.junit.internal.requests.ClassRequest;
import org.junit.internal.runners.model.EachTestNotifier;
import org.junit.runner.Description;
import org.junit.runner.Request;
import org.junit.runner.RunWith;
import org.junit.runner.Runner;
import org.junit.runner.manipulation.Filter;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.Parameterized;
import org.junit.runners.model.FrameworkMethod;
@@ -284,12 +285,31 @@ public class JUnit4TestRunnerUtil {
return new ClassRequest(clazz) {
public Runner getRunner() {
try {
return new IgnoreIgnoredTestJUnit4ClassRunner(clazz, recursively);
return new AllDefaultPossibilitiesBuilder(true) {
protected IgnoredBuilder ignoredBuilder() {
return new IgnoredBuilder() {
public Runner runnerForClass(Class testClass) {
return null;
}
};
}
protected JUnit4Builder junit4Builder() {
return new JUnit4Builder() {
public Runner runnerForClass(Class testClass) throws Throwable {
return new BlockJUnit4ClassRunner(testClass) {
protected boolean isIgnored(FrameworkMethod child) {
return false;
}
};
}
};
}
}.runnerForClass(clazz);
}
catch (Exception ignored) {
//return super runner
catch (Throwable throwable) {
return super.getRunner();
}
return super.getRunner();
}
};
}
@@ -343,36 +363,4 @@ public class JUnit4TestRunnerUtil {
public static String testsFoundInPackageMesage(int testCount, String name) {
return MessageFormat.format(ourBundle.getString("tests.found.in.package"), new Object[]{new Integer(testCount), name});
}
private static class IgnoreIgnoredTestJUnit4ClassRunner extends BlockJUnit4ClassRunner {
private final boolean myRecursively;
public IgnoreIgnoredTestJUnit4ClassRunner(Class clazz, boolean recursively) throws Exception {
super(clazz);
myRecursively = recursively;
}
protected void runChild(FrameworkMethod method, RunNotifier notifier) {
if (!myRecursively){
super.runChild(method, notifier);
return;
}
final Description description = describeChild(method);
final EachTestNotifier eachNotifier = new EachTestNotifier(notifier, description);
eachNotifier.fireTestStarted();
try {
methodBlock(method).evaluate();
}
catch (AssumptionViolatedException e) {
eachNotifier.addFailedAssumption(e);
}
catch (Throwable e) {
eachNotifier.addFailure(e);
}
finally {
eachNotifier.fireTestFinished();
}
}
}
}
@@ -20,7 +20,7 @@ except ImportError:
IS_JYTHON = False
from _pydev_bundle import _pydev_imports_tipper
from _pydevd_bundle import pydevd_vars
from _pydevd_bundle import pydevd_xml
dir2 = _pydev_imports_tipper.generate_imports_tip_for_module
@@ -176,8 +176,8 @@ def generate_completions_as_xml(frame, act_tok):
#list(tuple(name, descr, parameters, type))
completions = completer.complete(act_tok)
valid_xml = pydevd_vars.make_valid_xml_value
quote = pydevd_vars.quote
valid_xml = pydevd_xml.make_valid_xml_value
quote = pydevd_xml.quote
msg = ["<xml>"]
@@ -25,6 +25,7 @@ class TestCase(unittest.TestCase):
'sys.path.append(r\'%s\'); '
'import pydevd; pydevd.settrace(host=\'127.0.0.1\', port=0, suspend=False, '
'trace_only_current_thread=False, patch_multiprocessing=True); '
'sys.original_argv = []; '
'connect("127.0.0.1")' % pydev_src_dir,
pydev_monkey.patch_arg_str_win(check)
)
@@ -48,6 +49,7 @@ class TestCase(unittest.TestCase):
(
'import sys; sys.path.append(r\'%s\'); import pydevd; '
'pydevd.settrace(host=\'127.0.0.1\', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True); '
'sys.original_argv = []; '
'connect(\\"127.0.0.1\\")'
) % pydev_src_dir
])
+5
View File
@@ -0,0 +1,5 @@
root = true
[*]
indent_style = space
indent_size = 2
+3
View File
@@ -0,0 +1,3 @@
/.gradle/
/build/
/.idea/
+26
View File
@@ -0,0 +1,26 @@
buildscript {
repositories { jcenter() }
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:+"
}
}
apply plugin: 'kotlin'
repositories { jcenter() }
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:1.0.+"
compile "org.apache.logging.log4j:log4j-api:2.+"
compile "org.apache.logging.log4j:log4j-core:2.+"
testCompile "junit:junit:4.+"
testCompile "org.assertj:assertj-core:3.+"
}
jar {
manifest {
attributes "Main-Class" : "com.intellij.updater.mock.MainKt"
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
}
Binary file not shown.
Binary file not shown.
+16
View File
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="STDOUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
+1
View File
@@ -0,0 +1 @@
rootProject.name = 'update-server-mock'
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2016 JetBrains s.r.o.
*
* 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.intellij.updater.mock
class Generator {
private val patch = this.javaClass.classLoader.getResourceAsStream("patch/patch.jar").use { it.readBytes() }
fun generateXml(productCode: String, buildId: String, eap: Boolean): String {
val status = if (eap) "eap" else "release"
return """
<!DOCTYPE products SYSTEM "updates.dtd">
<products>
<product name="Mock Product">
<code>$productCode</code>
<channel id="MOCK" status="$status" licensing="$status">
<build number="9999.0.0" version="Mock">
<message><![CDATA[A mock update. For testing purposes only.]]></message>
<button name="Download" url="https://www.jetbrains.com/" download="true"/>
<patch from="$buildId" size="from 0 to ∞"/>
</build>
</channel>
</product>
</products>""".trimIndent()
}
fun generatePatch(): ByteArray = patch
}
@@ -0,0 +1,102 @@
/*
* Copyright (c) 2016 JetBrains s.r.o.
*
* 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.intellij.updater.mock
import com.sun.net.httpserver.HttpServer
import org.apache.logging.log4j.LogManager
import java.net.HttpURLConnection.*
import java.net.InetSocketAddress
import java.net.URI
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
class Server(private val port: Int, private val generator: Generator) {
private val server = HttpServer.create()
private val log = LogManager.getLogger(Server::class.java)
private val buildFormat = "([A-Z]+)-([0-9.]+)".toRegex()
private val tsFormat = DateTimeFormatter.ofPattern("dd/MMM/yyyy:kk:mm:ss ZZ")
fun start() {
server.bind(InetSocketAddress("localhost", port), 0)
server.createContext("/") { ex ->
val response = try {
process(ex.requestMethod, ex.requestURI)
}
catch(e: Exception) {
log.error(e)
Response(HTTP_INTERNAL_ERROR, "Internal error")
}
try {
val contentType = if (response.type.startsWith("text/")) "${response.type}; charset=utf-8" else response.type
ex.responseHeaders.add("Content-Type", contentType)
ex.sendResponseHeaders(response.code, response.bytes.size.toLong())
ex.responseBody.write(response.bytes)
ex.close()
log.info("${ex.remoteAddress.address.hostAddress} - - [${tsFormat.format(ZonedDateTime.now())}]" +
" \"${ex.requestMethod} ${ex.requestURI}\" ${ex.responseCode} ${response.bytes.size}")
}
catch(e: Exception) {
log.error(e)
}
}
server.start()
}
private fun process(method: String, uri: URI): Response {
val path = uri.path
return when {
method != "GET" -> Response(HTTP_BAD_REQUEST, "Didn't get")
path == "/" -> Response(HTTP_OK, "Mock Update Server")
path == "/updates/updates.xml" -> xml(uri.query ?: "")
path.startsWith("/patches/") -> patch(path)
else -> Response(HTTP_NOT_FOUND, "Miss")
}
}
private fun xml(query: String): Response {
val parameters = query.splitToSequence('&')
.filter { it.startsWith("build") || it.startsWith("eap") }
.map { it.split('=', limit = 2) }
.map { it[0] to if (it.size > 1) it[1] else "" }
.toMap()
val build = parameters["build"]
if (build != null) {
val match = buildFormat.find(build)
val productCode = match?.groups?.get(1)?.value
val buildId = match?.groups?.get(2)?.value
if (productCode != null && buildId != null) {
val xml = generator.generateXml(productCode, buildId, "eap" in parameters)
return Response(HTTP_OK, "text/xml", xml.toByteArray())
}
}
return Response(HTTP_BAD_REQUEST, "Bad parameters")
}
private fun patch(path: String): Response = when {
path.endsWith(".jar") -> Response(HTTP_OK, "binary/octet-stream", generator.generatePatch())
else -> Response(HTTP_BAD_REQUEST, "Bad path")
}
private class Response(val code: Int, val type: String, val bytes: ByteArray) {
constructor(code: Int, text: String) : this(code, "text/plain", text.toByteArray())
}
}
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2016 JetBrains s.r.o.
*
* 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.intellij.updater.mock
import org.apache.logging.log4j.LogManager
fun main(args: Array<String>) {
if (args.size != 1) {
println("usage: java -jar update-server-mock.jar <port>")
System.exit(1)
}
val log = LogManager.getLogger(Server::class.java)
val port = args[0]
try {
log.info("starting the server on port '$port' ...")
val generator = Generator()
Server(port.toInt(), generator).start()
log.info("ready")
}
catch(e: Exception) {
log.error("failed to start the server", e)
System.exit(2)
}
}
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2016 JetBrains s.r.o.
*
* 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.intellij.updater.mock
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test
class GeneratorTest {
@Test fun generateXml() {
val xml = Generator().generateXml("IC", "163.11.22", false)
assertThat(xml).contains("patch from=\"163.11.22\"").contains("status=\"release\"")
}
@Test fun generatePatch() {
val patch = Generator().generatePatch()
assertThat(patch).isNotEmpty()
}
}
+34
View File
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
<orderEntry type="module-library" scope="PROVIDED">
<library name="log4j-api">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/log4j-api-2.6.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library" scope="PROVIDED">
<library name="log4j-core">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/log4j-core-2.6.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
<orderEntry type="library" scope="TEST" name="assertJ" level="project" />
</component>
</module>