This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 262132

Summary: Refactor doesn't work with NOT primitive type/ serialized form component property values
Product: guibuilder Reporter: rbelatamas <rbelatamas>
Component: CodeAssignee: issues@guibuilder <issues>
Status: NEW ---    
Severity: normal    
Priority: P3    
Version: 8.1   
Hardware: PC   
OS: Windows 7   
Issue Type: DEFECT Exception Reporter:
Attachments: An example

Description rbelatamas 2016-05-18 02:16:16 UTC
Created attachment 159790 [details]
An example

These values are stored in form files in serialized encoded form, and the refactoring doesn't handle this situation. Example case when the type is an enumeration.

An example:
-----------
<Component class="hu.wfs.lib.gui.entitas.SzdbfTSZ" name="szdbfTSZ_Nyitoegyenleg">
  <Properties>
    <Property name="szerkesztendoTulajdonsagnev" type="java.lang.String" value="nyitoegyenleg"/>
    <Property name="tipus" type="hu.wfs.lib.gui.Szdbf$Tipus" editor="hu.wfs.lib.gui.SzdbfTipusEditor">
      <SerializedValue value="-84,-19,0,5,126,114,0,26,104,117,46,119,102,115,46,108,105,98,46,103,117,105,46,83,122,100,98,102,36,84,105,112,117,115,0,0,0,0,0,0,0,0,18,0,0,120,114,0,14,106,97,118,97,46,108,97,110,103,46,69,110,117,109,0,0,0,0,0,0,0,0,18,0,0,120,112,116,0,12,76,69,66,69,71,79,80,79,78,84,79,83"/>
    </Property>
  </Properties>
</Component> 

Watch this row:
---------------
<SerializedValue value="[encoded value]"/>

Workaround tip:
---------------
You have to decode, convert(type to type) and encode the new value manually. This methods can help you maybe:

URL:
http://grepcode.com/file_/bits.netbeans.org/maven2/org.netbeans.modules/org-netbeans-modules-form/RELEASE72/org/netbeans/modules/form/GandalfPersistenceManager.java/?v=source

/** Decodes a value from String containing textual representation of
 * serialized stream.
 * 
 * @param strValue value to decode.
 * @return decoded object
 * @exception IOException thrown if an error occurres during deserializing
 *            the object
 * @throws java.lang.ClassNotFoundException if the corresponding class cannot be loaded.
 */
public static Object decodeValue(String strValue)
    throws IOException, ClassNotFoundException
{
    if (strValue == null || strValue.length() == 0)
	return null;

    char[] bisChars = strValue.toCharArray();
    byte[] bytes = new byte[bisChars.length];
    StringBuffer singleNum = new StringBuffer();
    int count = 0;
    for (int i = 0; i < bisChars.length; i++) {
	if (',' == bisChars[i]) {
	    bytes[count++] = Byte.parseByte(singleNum.toString());
	    singleNum = new StringBuffer();
	} else {
	    singleNum.append(bisChars[i]);
	}
    }

    // add the last byte
    bytes[count++] = Byte.parseByte(singleNum.toString());
    ByteArrayInputStream bis = new ByteArrayInputStream(bytes, 0, count);
    return new ObjectInputStream(bis).readObject();
}    

/** Encodes specified value to a String containing textual representation of serialized stream.
 * 
 * @param value value to encode.
 * @return String containing textual representation of the serialized object
 * @throws java.io.IOException when some problem occurs during encoding.
 */
public static String encodeValue(Object value) throws IOException {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(bos);

    oos.writeObject(value);
    oos.close();

    byte[] bosBytes = bos.toByteArray();
    StringBuilder buf = new StringBuilder(bosBytes.length*4);
    for (int i=0; i < bosBytes.length; i++) {
	if (i+1 < bosBytes.length)
	    buf.append(bosBytes[i]).append(","); // NOI18N
	else
	    buf.append("").append(bosBytes[i]); // NOI18N
    }
    return buf.toString();
}

Actual Netbeans version:
------------------------
Product Version: NetBeans IDE 8.1 (Build 201510222201)
Java: 1.8.0_77; Java HotSpot(TM) 64-Bit Server VM 25.77-b03
Runtime: Java(TM) SE Runtime Environment 1.8.0_77-b03
System: Windows 7 version 6.1 running on amd64; Cp1250; hu_HU (nb)
Comment 1 Tomas Pavek 2016-05-18 15:40:19 UTC
Interesting problem. It may be possible to deserialize an instance into a different class (i.e. the same class renamed) which then could be serialized back to the GUI form. The problem here is that when the refactoring is running, the GUI builder does not have the new class yet (it is probably not renamed yet, or definitely not compiled). It will be after the refactoring completes. So all GUI refactorings are simplified to deal with this limitation somehow. Here it seems like it can't be overcome.

But if there is a trick to read serialized content for a different class (http://stackoverflow.com/questions/2358886/how-can-i-deserialize-the-object-if-it-was-moved-to-another-package-or-renamed), maybe there is also an opposite trick for writing. That would have to be investigated.
Comment 2 rbelatamas 2016-05-18 19:44:57 UTC
How can I edit my first comment to insert a break into the long line? :)