/* * RHQ Management Platform * Copyright (C) 2005-2011 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as * published by the Free Software Foundation, and/or the GNU Lesser * General Public License, version 2.1, also as published by the Free * Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License and the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU General Public License * and the GNU Lesser General Public License along with this program; * if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.rhq.core.domain.configuration; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * This type of {@link Property} stores a simple Java primitive value in string form. Null values are allowed. * * @author Jason Dobies * @author Greg Hinkle */ @DiscriminatorValue("property") @Entity @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement public class PropertySimple extends Property implements Serializable { private static final long serialVersionUID = 1L; public static final int MAX_VALUE_LENGTH = 2000; /** * This is the special value for simple properties of type PASSWORD that are masked. Masking and unmasking of * PASSWORD properties is done by the ConfigurationManagerBean SLSB, and, for the sake of security, prevents RHQ * clients from being able to view the current value of PASSWORD properties. The value is made obscure enough to * make the chances of it being the same as the property's unmasked value next to nil. */ public static final String MASKED_VALUE = "_._._[MaSKeD]_._._"; @Column(name = "string_value", length = MAX_VALUE_LENGTH) private String stringValue; @Column(name = "override") private Boolean override; /** * Constructor for {@link PropertySimple} that stores a <code>null</code> value. * NOTE: When using this constructor, you need to supply a name via #setName manually. */ public PropertySimple() { override = Boolean.FALSE; } protected PropertySimple(PropertySimple original, boolean keepId) { super(original, keepId); this.stringValue = original.stringValue; this.override = original.override; } /** * Constructs a property that has the given name with the given value. The value's <code>toString</code> * representation will be stored in this object - <code>value</code> itself will not be stored (that is, this object * will not hold a reference to <code>value</code>). * * @param name * @param value */ public PropertySimple(@NotNull String name, @Nullable Object value) { setName(name); setValue(value); } /** * Sets the value of this property to the <code>toString</code> form of the given <code>value</code>. This object * will not hold a reference to <code>value</code>. * * @param value */ public void setValue(@Nullable Object value) { if (value == null) { stringValue = null; return; } String valueAsString = value.toString(); stringValue = valueAsString.length() > MAX_VALUE_LENGTH ? valueAsString.substring(0, MAX_VALUE_LENGTH) : valueAsString; } /** * Returns the value (in string form) of this property, which may be <code>null</code>. * * <p>This may return <code>null</code></p> * * @return string form of the property value */ @Nullable public String getStringValue() { return stringValue; } /** * Sets the value of this property to the given <code>value</code>. * * <p>Calling this method is the same as if calling {@link #setValue(Object)}.</p> * * @param value */ public void setStringValue(@Nullable String value) { this.setValue(value); } /** * Returns this property value as a Boolean. See {@link Boolean#parseBoolean(String)} for the behavior of this * method. * * <p>This may return <code>null</code></p> * * @return the value as a Boolean */ @Nullable public Boolean getBooleanValue() { return (stringValue == null) ? null : Boolean.valueOf(stringValue); } /** * Sets the value of this property to the <code>toString</code> form of the given <code>value</code>. This object * will not hold a reference to the <code>value</code>. * * <p>Calling this method is the same as if calling {@link #setValue(Object)}.</p> * * @param value */ public void setBooleanValue(@Nullable Boolean value) { this.setValue(value); } /** * Returns this property value as a Long. See {@link Long#parseLong(String)} for the behavior of this method. * * <p>This may return <code>null</code></p> * * @return the value as a Long */ @Nullable public Long getLongValue() { return (stringValue == null) ? null : Long.valueOf(stringValue); } /** * Sets the value of this property to the <code>toString</code> form of the given <code>value</code>. This object * will not hold a reference to the <code>value</code>. * * <p>Calling this method is the same as if calling {@link #setValue(Object)}.</p> * * @param value */ public void setLongValue(@Nullable Long value) { this.setValue(value); } /** * Returns this property value as a Integer. See {@link Integer#parseInt(String)} for the behavior of this method. * * <p>This may return <code>null</code></p> * * @return the value as an Integer */ @Nullable public Integer getIntegerValue() { return (stringValue == null) ? null : Integer.valueOf(stringValue); } /** * Sets the value of this property to the <code>toString</code> form of the given <code>value</code>. This object * will not hold a reference to the <code>value</code>. * * <p>Calling this method is the same as if calling {@link #setValue(Object)}.</p> * * @param value */ public void setIntegerValue(@Nullable Integer value) { this.setValue(value); } /** * Returns this property value as a Float. See {@link Float#parseFloat(String)} for the behavior of this method. * * <p>This may return <code>null</code></p> * * @return the value as a Float */ @Nullable public Float getFloatValue() { return (stringValue == null) ? null : Float.valueOf(stringValue); } /** * Sets the value of this property to the <code>toString</code> form of the given <code>value</code>. This object * will not hold a reference to the <code>value</code>. * * <p>Calling this method is the same as if calling {@link #setValue(Object)}.</p> * * @param value */ public void setFloatValue(@Nullable Float value) { this.setValue(value); } /** * Returns this property value as a Double. See {@link Double#parseDouble(String)} for the behavior of this method. * * <p>This may return <code>null</code></p> * * @return the value as a Double */ @Nullable public Double getDoubleValue() { return (stringValue == null) ? null : Double.valueOf(stringValue); } /** * Sets the value of this property to the <code>toString</code> form of the given <code>value</code>. This object * will not hold a reference to the <code>value</code>. * * <p>Calling this method is the same as if calling {@link #setValue(Object)}.</p> * * @param value */ public void setDoubleValue(@Nullable Double value) { this.setValue(value); } public Boolean getOverride() { return this.override; } public void setOverride(Boolean override) { this.override = override; } public boolean isMasked() { return MASKED_VALUE.equals(this.stringValue); } public void mask() { // Don't mask properties with null values (i.e. unset properties), otherwise they will appear to have a // value when rendered in the GUI (see http://jira.jboss.com/jira/browse/JBNADM-2248). if (this.stringValue != null) { this.stringValue = MASKED_VALUE; } } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if ((obj == null) || !(obj instanceof PropertySimple)) { return false; } if (!super.equals(obj)) { return false; // superclass checks equality of the name fields } PropertySimple that = (PropertySimple) obj; // Treat empty string as if it were null See JBNADM-2715 String compareToA = ((this.stringValue != null) && (this.stringValue.length() == 0)) ? null : this.stringValue; String compareToB = ((that.stringValue != null) && (that.stringValue.length() == 0)) ? null : that.stringValue; if ((compareToA != null) ? (!compareToA.equals(compareToB)) : (compareToB != null)) { return false; } return true; } @Override public int hashCode() { int result = super.hashCode(); // superclass hashCode is derived from the name field result = (31 * result) + ((this.stringValue != null) ? this.stringValue.hashCode() : 0); return result; } public PropertySimple deepCopy(boolean keepId) { return new PropertySimple(this, keepId); } @Override protected void appendToStringInternals(StringBuilder str) { super.appendToStringInternals(str); str.append(", value=").append(getStringValue()); str.append(", override=").append(getOverride()); } }