diff --git a/core/src/main/java/hudson/XmlFile.java b/core/src/main/java/hudson/XmlFile.java index 5b12b63a40..49e6554043 100644 --- a/core/src/main/java/hudson/XmlFile.java +++ b/core/src/main/java/hudson/XmlFile.java @@ -7,6 +7,7 @@ import com.thoughtworks.xstream.io.xml.XppReader; import hudson.util.AtomicFileWriter; import hudson.util.IOException2; import hudson.util.XStream2; +import hudson.model.Descriptor; import java.io.BufferedReader; import java.io.File; @@ -18,6 +19,46 @@ import java.io.Reader; /** * Represents an XML data file that Hudson uses as a data file. * + * + *
+ * Changing data format requires a particular care so that users with + * the old data format can migrate to the newer data format smoothly. + * + *
+ * Adding a field is the easiest. When you read an old XML that does + * not have any data, the newly added field is left to the VM-default + * value (if you let XStream create the object, such as + * {@link #read()} — which is the majority), or to the value initialized by the + * constructor (if the object is created via new and then its + * value filled by XStream, such as {@link #unmarshal(Object)}.) + * + *
+ * Removing a field requires that you actually leave the field with + * transient keyword. When you read the old XML, XStream + * will set the value to this field. But when the data is saved, + * the field will no longer will be written back to XML. + * (It might be possible to tweak XStream so that we can simply + * remove fields from the class. Any help appreciated.) + * + *
+ * Changing the data structure is usually a combination of the two + * above. You'd leave the old data store with transient, + * and then add the new data. When you are reading the old XML, + * only the old field will be set. When you are reading the new XML, + * only the new field will be set. You'll then need to alter the code + * so that it will be able to correctly handle both situations, + * and that as soon as you see data in the old field, you'll have to convert + * that into the new data structure, so that the next save operation + * will write the new data (otherwise you'll end up losing the data, because + * old fields will be never written back.) + * + *
+ * In some limited cases (specifically when the class is the root object + * to be read from XML, such as {@link Descriptor}), it is posible + * to completely and drastically change the data format. See + * {@link Descriptor#load()} for more about this technique. + * * @author Kohsuke Kawaguchi */ public final class XmlFile {