IDEA-166393 Reapplying default value is not saved correctly

This commit is contained in:
Vladimir Krivosheev
2017-03-07 15:08:13 +01:00
parent 91da8d78f3
commit c686e98d75
7 changed files with 165 additions and 66 deletions
@@ -27,6 +27,7 @@ import com.intellij.profile.codeInspection.BaseInspectionProfileManager
import com.intellij.profile.codeInspection.InspectionProfileManager
import com.intellij.profile.codeInspection.ProjectInspectionProfileManager
import com.intellij.util.xmlb.annotations.Transient
import org.jdom.Element
const val DEFAULT_PROFILE_NAME = "Default"
val BASE_PROFILE by lazy { InspectionProfileImpl(DEFAULT_PROFILE_NAME) }
@@ -120,6 +121,16 @@ abstract class NewInspectionProfile(name: String, private var profileManager: Ba
}
protected abstract fun initialize(project: Project?)
fun copyFrom(profile: InspectionProfileImpl) {
var element = profile.writeScheme()
if (element.name == "component") {
element = element.getChild("profile")
}
readExternal(element)
}
abstract fun readExternal(element: Element)
}
fun createSimple(name: String, project: Project, toolWrappers: List<InspectionToolWrapper<*, *>>): InspectionProfileImpl {
@@ -143,9 +143,8 @@ public class InspectionProfileImpl extends NewInspectionProfile {
return level;
}
@Override
public void readExternal(@NotNull Element element) {
super.readExternal(element);
mySerializer.readExternal(this, element);
final Element highlightElement = element.getChild(USED_LEVELS);
if (highlightElement != null) {
@@ -208,7 +207,8 @@ public class InspectionProfileImpl extends NewInspectionProfile {
return myDataHolder.read();
}
Element element = super.writeScheme();
Element element = new Element(PROFILE);
writeExternal(element);
if (isProjectLevel()) {
element.setAttribute("version", "1.0");
}
@@ -222,12 +222,11 @@ public class InspectionProfileImpl extends NewInspectionProfile {
return element;
}
@Override
public void writeExternal(@NotNull Element element) {
// must be first - compatibility
element.setAttribute(VERSION_TAG, VALID_VERSION);
super.writeExternal(element);
mySerializer.writeExternal(this, element);
synchronized (myLock) {
if (!wasInitialized()) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
* Copyright 2000-2017 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.
@@ -18,7 +18,6 @@ package com.intellij.profile;
import com.intellij.openapi.options.ExternalizableScheme;
import com.intellij.util.xmlb.SmartSerializer;
import com.intellij.util.xmlb.annotations.OptionTag;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
/**
@@ -30,7 +29,7 @@ public abstract class ProfileEx implements Comparable, ExternalizableScheme {
public static final String NAME = "name";
public static final String PROFILE = "profile";
private final SmartSerializer mySerializer;
protected final SmartSerializer mySerializer;
@NotNull
protected String myName;
@@ -57,14 +56,6 @@ public abstract class ProfileEx implements Comparable, ExternalizableScheme {
myName = name;
}
public void readExternal(Element element) {
mySerializer.readExternal(this, element);
}
public void writeExternal(@NotNull Element element) {
mySerializer.writeExternal(this, element, false);
}
public boolean equals(Object o) {
return this == o || o instanceof ProfileEx && myName.equals(((ProfileEx)o).myName);
}
@@ -80,19 +71,4 @@ public abstract class ProfileEx implements Comparable, ExternalizableScheme {
}
return 0;
}
public final void copyFrom(@NotNull ProfileEx profile) {
Element element = profile.writeScheme();
if (element.getName().equals("component")) {
element = element.getChild("profile");
}
readExternal(element);
}
@NotNull
public Element writeScheme() {
Element element = new Element(PROFILE);
writeExternal(element);
return element;
}
}
@@ -19,6 +19,7 @@ import com.intellij.openapi.util.ModificationTracker
import com.intellij.util.SmartList
import com.intellij.util.xmlb.Accessor
import com.intellij.util.xmlb.SerializationFilter
import com.intellij.util.xmlb.annotations.Transient
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
@@ -26,7 +27,8 @@ abstract class BaseState : SerializationFilter, ModificationTracker {
// if property value differs from default
private val properties: MutableList<StoredProperty> = SmartList()
@Volatile internal var modificationCount: Long = 0
@Volatile
internal var modificationCount: Long = 0
// reset on load state
fun resetModificationCount() {
@@ -52,6 +54,15 @@ abstract class BaseState : SerializationFilter, ModificationTracker {
return result
}
/**
* Empty string is always normalized to null.
*/
fun string(defaultValue: String? = null): ReadWriteProperty<BaseState, String?> {
val result = StringStoredProperty(defaultValue)
properties.add(result)
return result
}
fun storedProperty(defaultValue: Int = 0): ReadWriteProperty<BaseState, Int> {
val result = IntStoredProperty(defaultValue)
properties.add(result)
@@ -70,6 +81,7 @@ abstract class BaseState : SerializationFilter, ModificationTracker {
return result
}
@Transient
override fun getModificationCount(): Long {
var result = modificationCount
for (property in properties) {
@@ -97,27 +109,49 @@ abstract class BaseState : SerializationFilter, ModificationTracker {
builder.setLength(builder.length - 1)
return builder.toString()
}
fun copyFrom(state: BaseState) {
assert(state.properties.size == properties.size)
for ((index, property) in properties.withIndex()) {
val otherProperty = state.properties.get(index)
if (property.name != null) {
if (otherProperty.name == null) {
otherProperty.name = property.name
}
else {
assert(otherProperty.name == property.name)
}
}
property.setValue(otherProperty)
}
}
}
internal interface StoredProperty {
val defaultValue: Any?
val value: Any?
val name: String?
var name: String?
fun setValue(other: StoredProperty)
}
private class ObjectStoredProperty<T>(override val defaultValue: T) : ReadWriteProperty<BaseState, T>, StoredProperty {
override var value = defaultValue
override var name: String? = null
override operator fun getValue(thisRef: BaseState, property: KProperty<*>) = value
override operator fun getValue(thisRef: BaseState, property: KProperty<*>): T {
name = property.name
return value
}
@Suppress("UNCHECKED_CAST")
override fun setValue(thisRef: BaseState, property: KProperty<*>, @Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE") newValue: T) {
name = property.name
if (value != newValue) {
thisRef.modificationCount++
name = property.name
value = newValue
}
}
@@ -127,20 +161,64 @@ private class ObjectStoredProperty<T>(override val defaultValue: T) : ReadWriteP
override fun hashCode() = value?.hashCode() ?: 0
override fun toString() = if (value === defaultValue) "" else value?.toString() ?: super.toString()
override fun setValue(other: StoredProperty) {
@Suppress("UNCHECKED_CAST")
value = (other as ObjectStoredProperty<T>).value
}
}
private class StringStoredProperty(override val defaultValue: String?) : ReadWriteProperty<BaseState, String?>, StoredProperty {
override var value = defaultValue
override var name: String? = null
override operator fun getValue(thisRef: BaseState, property: KProperty<*>): String? {
name = property.name
return value
}
@Suppress("UNCHECKED_CAST")
override fun setValue(thisRef: BaseState, property: KProperty<*>, @Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE") _newValue: String?) {
name = property.name
var newValue = _newValue
if (newValue != null && newValue.isEmpty()) {
newValue = null
}
if (value != newValue) {
thisRef.modificationCount++
value = newValue
}
}
override fun equals(other: Any?) = this === other || (other is ObjectStoredProperty<*> && value == other.value)
override fun hashCode() = value?.hashCode() ?: 0
override fun toString() = if (value == defaultValue) "" else value ?: super.toString()
override fun setValue(other: StoredProperty) {
value = (other as StringStoredProperty).value
}
}
private class IntStoredProperty(override val defaultValue: Int) : ReadWriteProperty<BaseState, Int>, StoredProperty {
override var value = defaultValue
override var name: String? = null
override operator fun getValue(thisRef: BaseState, property: KProperty<*>) = value
override operator fun getValue(thisRef: BaseState, property: KProperty<*>): Int {
name = property.name
return value
}
@Suppress("UNCHECKED_CAST")
override fun setValue(thisRef: BaseState, property: KProperty<*>, @Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE") newValue: Int) {
name = property.name
if (value != newValue) {
thisRef.modificationCount++
name = property.name
value = newValue
}
}
@@ -150,20 +228,28 @@ private class IntStoredProperty(override val defaultValue: Int) : ReadWritePrope
override fun hashCode() = value.hashCode()
override fun toString() = if (value == defaultValue) "" else value.toString()
override fun setValue(other: StoredProperty) {
value = (other as IntStoredProperty).value
}
}
private class FloatStoredProperty(override val defaultValue: Float) : ReadWriteProperty<BaseState, Float>, StoredProperty {
override var value = defaultValue
override var name: String? = null
override operator fun getValue(thisRef: BaseState, property: KProperty<*>) = value
override operator fun getValue(thisRef: BaseState, property: KProperty<*>): Float {
name = property.name
return value
}
@Suppress("UNCHECKED_CAST")
override fun setValue(thisRef: BaseState, property: KProperty<*>, @Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE") newValue: Float) {
name = property.name
if (value != newValue) {
thisRef.modificationCount++
name = property.name
value = newValue
}
}
@@ -173,4 +259,8 @@ private class FloatStoredProperty(override val defaultValue: Float) : ReadWriteP
override fun hashCode() = value.hashCode()
override fun toString() = if (value == defaultValue) "" else value.toString()
override fun setValue(other: StoredProperty) {
value = (other as FloatStoredProperty).value
}
}
+5 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
* Copyright 2000-2017 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.
@@ -79,14 +79,13 @@ class CopyrightManager(private val project: Project, schemeManagerFactory: Schem
val options = Options()
private val schemeWriter = { scheme: CopyrightProfile ->
val element = Element("copyright")
scheme.writeExternal(element)
val element = scheme.writeScheme()
if (project.isDirectoryBased) wrapScheme(element) else element
}
private val schemeManagerIprProvider = if (project.isDirectoryBased) null else SchemeManagerIprProvider("copyright")
val schemeManager = schemeManagerFactory.create("copyright", object : LazySchemeProcessor<SchemeWrapper<CopyrightProfile>, SchemeWrapper<CopyrightProfile>>() {
val schemeManager = schemeManagerFactory.create("copyright", object : LazySchemeProcessor<SchemeWrapper<CopyrightProfile>, SchemeWrapper<CopyrightProfile>>("myName") {
override fun createScheme(dataHolder: SchemeDataHolder<SchemeWrapper<CopyrightProfile>>,
name: String,
attributeProvider: Function<String, String?>,
@@ -264,7 +263,8 @@ private class CopyrightLazySchemeWrapper(name: String,
element = element.getChild(subStateTagName)
}
scheme.readExternal(element)
element.deserializeInto(scheme)
scheme.resetModificationCount()
dataHolder.updateDigest(writer(scheme))
scheme
}
@@ -15,27 +15,50 @@
*/
package com.maddyhome.idea.copyright
import com.intellij.openapi.util.text.StringUtil
import com.intellij.profile.ProfileEx
import com.intellij.util.xmlb.SmartSerializer
import com.intellij.configurationStore.SerializableScheme
import com.intellij.configurationStore.serializeInto
import com.intellij.openapi.components.BaseState
import com.intellij.openapi.options.ExternalizableScheme
import com.intellij.util.xmlb.annotations.OptionTag
import com.intellij.util.xmlb.annotations.Transient
import com.maddyhome.idea.copyright.pattern.EntityUtil
import org.jdom.Element
class CopyrightProfile @JvmOverloads constructor(profileName: String = "") : ProfileEx(profileName, SmartSerializer()) {
companion object {
@JvmField
val DEFAULT_COPYRIGHT_NOTICE: String = EntityUtil.encode(
"Copyright (c) \$today.year. Lorem ipsum dolor sit amet, consectetur adipiscing elit. \n" +
"Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. \n" +
"Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. \n" +
"Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. \n" +
"Vestibulum commodo. Ut rhoncus gravida arcu. ")
@JvmField
val DEFAULT_COPYRIGHT_NOTICE: String = EntityUtil.encode(
"Copyright (c) \$today.year. Lorem ipsum dolor sit amet, consectetur adipiscing elit. \n" +
"Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. \n" +
"Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. \n" +
"Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. \n" +
"Vestibulum commodo. Ut rhoncus gravida arcu. ")
class CopyrightProfile @JvmOverloads constructor(profileName: String? = null) : ExternalizableScheme, BaseState(), SerializableScheme {
// ugly name to preserve compatibility
// must be not private because otherwise binding is not created for private accessor
@get:OptionTag("myName")
internal var profileName by string()
var notice by string(DEFAULT_COPYRIGHT_NOTICE)
var keyword by string(EntityUtil.encode("Copyright"))
var allowReplaceRegexp by string()
init {
// otherwise will be as default value and name will be not serialized
this.profileName = profileName
}
var notice = DEFAULT_COPYRIGHT_NOTICE
var keyword = EntityUtil.encode("Copyright")
@Transient
override fun getName() = profileName ?: ""
var allowReplaceRegexp: String? = null
set(allowReplaceRegexp) {
field = StringUtil.nullize(allowReplaceRegexp)
}
}//read external
override fun setName(value: String) {
profileName = value
}
override fun toString() = profileName ?: ""
override fun writeScheme(): Element {
val element = Element("copyright")
serializeInto(element)
return element
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
* Copyright 2000-2017 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.
@@ -28,7 +28,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.ui.DocumentAdapter;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.util.ui.UIUtil;
import com.maddyhome.idea.copyright.CopyrightProfile;
import com.maddyhome.idea.copyright.CopyrightProfileKt;
import com.maddyhome.idea.copyright.options.LanguageOptions;
import com.maddyhome.idea.copyright.options.Options;
import com.maddyhome.idea.copyright.pattern.EntityUtil;
@@ -340,7 +340,7 @@ public class TemplateCommentPanel implements SearchableConfigurable {
private void showPreview(LanguageOptions options) {
final String defaultCopyrightText = myNoCopyright.isSelected() ? "" : FileTypeUtil
.buildComment(fileType, VelocityHelper.evaluate(null, null, null, EntityUtil.decode(CopyrightProfile.DEFAULT_COPYRIGHT_NOTICE)), options);
.buildComment(fileType, VelocityHelper.evaluate(null, null, null, EntityUtil.decode(CopyrightProfileKt.DEFAULT_COPYRIGHT_NOTICE)), options);
SwingUtilities.invokeLater(() -> preview.setText(defaultCopyrightText));
}