159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.scene.plugins.blender.objects;
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.*;
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.BlenderContext;
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.file.BlenderInputStream;
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.file.FileBlockHeader;
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.file.Pointer;
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.file.Structure;
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.io.IOException;
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.ArrayList;
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.HashMap;
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.List;
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.Map;
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.logging.Logger;
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/**
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * The blender object's custom properties.
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * This class is valid for all versions of blender.
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author Marcin Roguski (Kaelthas)
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class Properties implements Cloneable, Savable {
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	private static final Logger		LOGGER				= Logger.getLogger(Properties.class.getName());
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	// property type
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public static final int			IDP_STRING			= 0;
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public static final int			IDP_INT				= 1;
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public static final int			IDP_FLOAT			= 2;
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public static final int			IDP_ARRAY			= 5;
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public static final int			IDP_GROUP			= 6;
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	// public static final int IDP_ID = 7;//this is not implemented in blender (yet)
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public static final int			IDP_DOUBLE			= 8;
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	// the following are valid for blender 2.5x+
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public static final int			IDP_IDPARRAY		= 9;
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public static final int			IDP_NUMTYPES		= 10;
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	protected static final String	RNA_PROPERTY_NAME	= "_RNA_UI";
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/** Default name of the property (used if the name is not specified in blender file). */
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	protected static final String	DEFAULT_NAME		= "Unnamed property";
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/** The name of the property. */
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	private String					name;
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/** The type of the property. */
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	private int						type;
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/** The subtype of the property. Defines the type of array's elements. */
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	private int						subType;
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/** The value of the property. */
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	private Object					value;
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/** The description of the property. */
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	private String					description;
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * This method loads the property from the belnder file.
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param idPropertyStructure
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *        the ID structure constining the property
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param blenderContext
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *        the blender context
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @throws BlenderFileException
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *         an exception is thrown when the belnder file is somehow invalid
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public void load(Structure idPropertyStructure, BlenderContext blenderContext) throws BlenderFileException {
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		name = idPropertyStructure.getFieldValue("name").toString();
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if (name == null || name.length() == 0) {
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			name = DEFAULT_NAME;
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		subType = ((Number) idPropertyStructure.getFieldValue("subtype")).intValue();
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		type = ((Number) idPropertyStructure.getFieldValue("type")).intValue();
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		// reading the data
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		Structure data = (Structure) idPropertyStructure.getFieldValue("data");
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		int len = ((Number) idPropertyStructure.getFieldValue("len")).intValue();
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		switch (type) {
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_STRING: {
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				Pointer pointer = (Pointer) data.getFieldValue("pointer");
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				BlenderInputStream bis = blenderContext.getInputStream();
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				FileBlockHeader dataFileBlock = blenderContext.getFileBlock(pointer.getOldMemoryAddress());
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				bis.setPosition(dataFileBlock.getBlockPosition());
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				value = bis.readString();
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				break;
8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_INT:
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				int intValue = ((Number) data.getFieldValue("val")).intValue();
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				value = Integer.valueOf(intValue);
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				break;
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_FLOAT:
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				int floatValue = ((Number) data.getFieldValue("val")).intValue();
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				value = Float.valueOf(Float.intBitsToFloat(floatValue));
8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				break;
8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_ARRAY: {
9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				Pointer pointer = (Pointer) data.getFieldValue("pointer");
9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				BlenderInputStream bis = blenderContext.getInputStream();
9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				FileBlockHeader dataFileBlock = blenderContext.getFileBlock(pointer.getOldMemoryAddress());
9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				bis.setPosition(dataFileBlock.getBlockPosition());
9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				int elementAmount = dataFileBlock.getSize();
9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				switch (subType) {
9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					case IDP_INT:
9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						elementAmount /= 4;
9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						int[] intList = new int[elementAmount];
9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						for (int i = 0; i < elementAmount; ++i) {
10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta							intList[i] = bis.readInt();
10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						}
10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						value = intList;
10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						break;
10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					case IDP_FLOAT:
10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						elementAmount /= 4;
10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						float[] floatList = new float[elementAmount];
10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						for (int i = 0; i < elementAmount; ++i) {
10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta							floatList[i] = bis.readFloat();
10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						}
11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						value = floatList;
11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						break;
11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					case IDP_DOUBLE:
11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						elementAmount /= 8;
11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						double[] doubleList = new double[elementAmount];
11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						for (int i = 0; i < elementAmount; ++i) {
11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta							doubleList[i] = bis.readDouble();
11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						}
11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						value = doubleList;
11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						break;
12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					default:
12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						throw new IllegalStateException("Invalid array subtype: " + subType);
12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				}
12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_GROUP:
12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				Structure group = (Structure) data.getFieldValue("group");
12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				List<Structure> dataList = group.evaluateListBase(blenderContext);
12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				List<Properties> subProperties = new ArrayList<Properties>(len);
12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				for (Structure d : dataList) {
12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					Properties properties = new Properties();
13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					properties.load(d, blenderContext);
13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					subProperties.add(properties);
13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				}
13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				value = subProperties;
13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				break;
13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_DOUBLE:
13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				int doublePart1 = ((Number) data.getFieldValue("val")).intValue();
13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				int doublePart2 = ((Number) data.getFieldValue("val2")).intValue();
13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				long doubleVal = (long) doublePart2 << 32 | doublePart1;
13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				value = Double.valueOf(Double.longBitsToDouble(doubleVal));
14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				break;
14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_IDPARRAY: {
14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				Pointer pointer = (Pointer) data.getFieldValue("pointer");
14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				List<Structure> arrays = pointer.fetchData(blenderContext.getInputStream());
14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				List<Object> result = new ArrayList<Object>(arrays.size());
14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				Properties temp = new Properties();
14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				for (Structure array : arrays) {
14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					temp.load(array, blenderContext);
14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					result.add(temp.value);
14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				}
15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				this.value = result;
15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				break;
15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_NUMTYPES:
15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				throw new UnsupportedOperationException();
15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				// case IDP_ID://not yet implemented in blender
15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				// return null;
15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			default:
15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				throw new IllegalStateException("Unknown custom property type: " + type);
15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		this.completeLoading();
16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * This method returns the name of the property.
16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @return the name of the property
16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public String getName() {
16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		return name;
16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * This method returns the description of the property.
17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @return the description of the property
17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public String getDescription() {
17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		return description;
17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * This method returns the type of the property.
18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @return the type of the property
18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public int getType() {
18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		return type;
18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * This method returns the value of the property.
18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * The type of the value depends on the type of the property.
19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @return the value of the property
19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public Object getValue() {
19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		return value;
19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * This method returns the same as getValue if the current property is of
19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * other type than IDP_GROUP and its name matches 'propertyName' param. If
19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * this property is a group property the method tries to find subproperty
20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * value of the given name. The first found value is returnes os <b>use this
20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * method wisely</b>. If no property of a given name is foung - <b>null</b>
20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * is returned.
20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *
20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param propertyName
20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the name of the property
20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @return found property value or <b>null</b>
20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	@SuppressWarnings("unchecked")
20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public Object findValue(String propertyName) {
21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if (name.equals(propertyName)) {
21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			return value;
21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		} else {
21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			if (type == IDP_GROUP) {
21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				List<Properties> props = (List<Properties>) value;
21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				for (Properties p : props) {
21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					Object v = p.findValue(propertyName);
21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					if (v != null) {
21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						return v;
21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					}
22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				}
22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
22359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		return null;
22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	@Override
22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public String toString() {
22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		StringBuilder sb = new StringBuilder();
22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		this.append(sb, new StringBuilder());
23059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		return sb.toString();
23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * This method appends the data of the property to the given string buffer.
23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param sb
23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *        string buffer
23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param indent
23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *        indent buffer
23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	@SuppressWarnings("unchecked")
24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	private void append(StringBuilder sb, StringBuilder indent) {
24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		sb.append(indent).append("name: ").append(name).append("\n\r");
24359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		sb.append(indent).append("type: ").append(type).append("\n\r");
24459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		sb.append(indent).append("subType: ").append(subType).append("\n\r");
24559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		sb.append(indent).append("description: ").append(description).append("\n\r");
24659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		indent.append('\t');
24759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		sb.append(indent).append("value: ");
24859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if (value instanceof Properties) {
24959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			((Properties) value).append(sb, indent);
25059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		} else if (value instanceof List) {
25159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			for (Object v : (List<Object>) value) {
25259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				if (v instanceof Properties) {
25359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					sb.append(indent).append("{\n\r");
25459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					indent.append('\t');
25559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					((Properties) v).append(sb, indent);
25659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					indent.deleteCharAt(indent.length() - 1);
25759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					sb.append(indent).append("}\n\r");
25859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				} else {
25959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					sb.append(v);
26059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				}
26159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
26259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		} else {
26359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			sb.append(value);
26459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
26559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		sb.append("\n\r");
26659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		indent.deleteCharAt(indent.length() - 1);
26759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
26859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
26959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
27059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * This method should be called after the properties loading.
27159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * It loads the properties from the _RNA_UI property and removes this property from the
27259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * result list.
27359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
27459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	@SuppressWarnings("unchecked")
27559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	protected void completeLoading() {
27659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if (this.type == IDP_GROUP) {
27759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			List<Properties> groupProperties = (List<Properties>) this.value;
27859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			Properties rnaUI = null;
27959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			for (Properties properties : groupProperties) {
28059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				if (properties.name.equals(RNA_PROPERTY_NAME) && properties.type == IDP_GROUP) {
28159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					rnaUI = properties;
28259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					break;
28359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				}
28459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
28559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			if (rnaUI != null) {
28659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				// removing the RNA from the result list
28759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				groupProperties.remove(rnaUI);
28859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
28959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				// loading the descriptions
29059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				Map<String, String> descriptions = new HashMap<String, String>(groupProperties.size());
29159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				List<Properties> propertiesRNA = (List<Properties>) rnaUI.value;
29259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				for (Properties properties : propertiesRNA) {
29359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					String name = properties.name;
29459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					String description = null;
29559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					List<Properties> rnaData = (List<Properties>) properties.value;
29659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					for (Properties rna : rnaData) {
29759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						if ("description".equalsIgnoreCase(rna.name)) {
29859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta							description = (String) rna.value;
29959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta							break;
30059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						}
30159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					}
30259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					descriptions.put(name, description);
30359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				}
30459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
30559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				// applying the descriptions
30659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				for (Properties properties : groupProperties) {
30759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					properties.description = descriptions.get(properties.name);
30859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				}
30959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
31059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
31159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
31259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
31359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	@Override
31459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	@SuppressWarnings({ "rawtypes", "unchecked" })
31559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public void write(JmeExporter ex) throws IOException {
31659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		OutputCapsule oc = ex.getCapsule(this);
31759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		oc.write(name, "name", DEFAULT_NAME);
31859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		oc.write(type, "type", 0);
31959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		oc.write(subType, "subtype", 0);
32059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		oc.write(description, "description", null);
32159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		switch (type) {
32259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_STRING:
32359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				oc.write((String) value, "value", null);
32459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				break;
32559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_INT:
32659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				oc.write((Integer) value, "value", 0);
32759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				break;
32859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_FLOAT:
32959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				oc.write((Float) value, "value", 0);
33059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				break;
33159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_ARRAY:
33259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				switch (subType) {
33359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					case IDP_INT:
33459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						oc.write((int[]) value, "value", null);
33559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						break;
33659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					case IDP_FLOAT:
33759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						oc.write((float[]) value, "value", null);
33859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						break;
33959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					case IDP_DOUBLE:
34059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						oc.write((double[]) value, "value", null);
34159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						break;
34259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					default:
34359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						LOGGER.warning("Cannot save the property's value! Invalid array subtype! Property: name: " + name + "; subtype: " + subType);
34459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				}
34559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_GROUP:
34659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				oc.writeSavableArrayList((ArrayList<Properties>) value, "value", null);
34759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				break;
34859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_DOUBLE:
34959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				oc.write((Double) value, "value", 0);
35059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				break;
35159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_IDPARRAY:
35259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				oc.writeSavableArrayList((ArrayList) value, "value", null);
35359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				break;
35459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_NUMTYPES:
35559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				LOGGER.warning("Numtypes value not supported! Cannot write it!");
35659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				break;
35759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			// case IDP_ID://not yet implemented in blender
35859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			// break;
35959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			default:
36059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				LOGGER.warning("Cannot save the property's value! Invalid type! Property: name: " + name + "; type: " + type);
36159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
36259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
36359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
36459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	@Override
36559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public void read(JmeImporter im) throws IOException {
36659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		InputCapsule ic = im.getCapsule(this);
36759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		name = ic.readString("name", DEFAULT_NAME);
36859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		type = ic.readInt("type", 0);
36959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		subType = ic.readInt("subtype", 0);
37059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		description = ic.readString("description", null);
37159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		switch (type) {
37259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_STRING:
37359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				value = ic.readString("value", null);
37459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				break;
37559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_INT:
37659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				value = Integer.valueOf(ic.readInt("value", 0));
37759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				break;
37859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_FLOAT:
37959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				value = Float.valueOf(ic.readFloat("value", 0.0f));
38059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				break;
38159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_ARRAY:
38259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				switch (subType) {
38359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					case IDP_INT:
38459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						value = ic.readIntArray("value", null);
38559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						break;
38659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					case IDP_FLOAT:
38759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						value = ic.readFloatArray("value", null);
38859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						break;
38959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					case IDP_DOUBLE:
39059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						value = ic.readDoubleArray("value", null);
39159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						break;
39259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					default:
39359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						LOGGER.warning("Cannot read the property's value! Invalid array subtype! Property: name: " + name + "; subtype: " + subType);
39459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				}
39559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_GROUP:
39659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				value = ic.readSavable("value", null);
39759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				break;
39859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_DOUBLE:
39959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				value = Double.valueOf(ic.readDouble("value", 0.0));
40059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				break;
40159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_IDPARRAY:
40259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				value = ic.readSavableArrayList("value", null);
40359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				break;
40459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case IDP_NUMTYPES:
40559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				LOGGER.warning("Numtypes value not supported! Cannot read it!");
40659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				break;
40759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			// case IDP_ID://not yet implemented in blender
40859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			// break;
40959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			default:
41059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				LOGGER.warning("Cannot read the property's value! Invalid type! Property: name: " + name + "; type: " + type);
41159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
41259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
41359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
41459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	@Override
41559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public int hashCode() {
41659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		final int prime = 31;
41759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		int result = 1;
41859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		result = prime * result + (description == null ? 0 : description.hashCode());
41959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		result = prime * result + (name == null ? 0 : name.hashCode());
42059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		result = prime * result + subType;
42159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		result = prime * result + type;
42259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		result = prime * result + (value == null ? 0 : value.hashCode());
42359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		return result;
42459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
42559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
42659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	@Override
42759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public boolean equals(Object obj) {
42859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if (this == obj) {
42959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			return true;
43059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
43159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if (obj == null) {
43259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			return false;
43359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
43459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if (this.getClass() != obj.getClass()) {
43559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			return false;
43659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
43759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		Properties other = (Properties) obj;
43859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if (description == null) {
43959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			if (other.description != null) {
44059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				return false;
44159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
44259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		} else if (!description.equals(other.description)) {
44359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			return false;
44459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
44559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if (name == null) {
44659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			if (other.name != null) {
44759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				return false;
44859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
44959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		} else if (!name.equals(other.name)) {
45059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			return false;
45159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
45259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if (subType != other.subType) {
45359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			return false;
45459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
45559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if (type != other.type) {
45659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			return false;
45759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
45859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if (value == null) {
45959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			if (other.value != null) {
46059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				return false;
46159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
46259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		} else if (!value.equals(other.value)) {
46359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			return false;
46459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
46559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		return true;
46659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
46759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
468