/* * FreeMarker: a tool that allows Java programs to generate HTML * output using templates. * Copyright (C) 1998-2004 Benjamin Geer * Email: beroul@users.sourceforge.net * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ package freemarker.template; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.ObjectStreamField; import java.io.Serializable; /** * <p> * A simple implementation of the {@link TemplateScalarModel} interface, using a * <code>String</code> or a <code>boolean</code>. * </p> * * <p> * All the public methods in this implementation are synchronized. * </p> * * @version $Id: SimpleScalar.java 987 2004-10-05 10:13:24Z run2000 $ * @see SimpleNumber * @see SimpleList * @see SimpleHash */ public class SimpleScalar implements TemplateScalarModel, Serializable { /** * The value of this <code>SimpleScalar</code> if it wraps a * <code>String</code>. */ protected String stringValue; /** * The value of this <code>SimpleScalar</code> if it wraps a * <code>boolean</code>. */ protected boolean booleanValue; /** Serialization id, for compatibility with 1.7 */ private static final long serialVersionUID = -1990000765027659736L; /** * Serialized form matches the form used in FreeMarker 1.7. This is actually * more verbose than required, but backward compatibility means we do it * this way. * * @serialField * stringValue String the <code>String</code> value of this * scalar * @serialField * booleanValue boolean the <code>boolean</code> value of * this scalar * @serialField * useBoolean boolean for backward compatibility, do we use * the String or the boolean value? */ private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField("stringValue", String.class), new ObjectStreamField("booleanValue", Boolean.TYPE), new ObjectStreamField("useBoolean", Boolean.TYPE) }; /** * Constructs an empty <code>SimpleScalar</code>. */ public SimpleScalar() { } /** * Constructs a <code>SimpleScalar</code> containing a string value. * * @param value * the string value. */ public SimpleScalar(String value) { setValue(value); } /** * Constructs a <code>SimpleScalar</code> containing a boolean value. * * @param value * the boolean value. */ public SimpleScalar(boolean value) { setValue(value); } /** * Is this <code>SimpleScalar</code> empty? * * @return <code>true</code> if this object is empty, otherwise * <code>false</code> */ public synchronized boolean isEmpty() throws TemplateModelException { return !booleanValue; } /** * Returns the scalar's value as a <code>String</code>. * * @return the <code>String</code> value of this scalar. */ public synchronized String getAsString() throws TemplateModelException { return stringValue; } /** * Sets the <code>String</code> value of this <code>SimpleScalar</code>. * * @param value * the <code>String</code> value. */ public synchronized void setValue(String value) { this.stringValue = value; this.booleanValue = (value != null) && (value.length() > 0); } /** * Sets the <code>boolean</code> value of this <tt>SimpleScalar</tt>. * * @param value * the <tcodet>boolean</code> value. */ public synchronized void setValue(boolean value) { this.booleanValue = value; this.stringValue = value ? Boolean.TRUE.toString() : Boolean.FALSE.toString(); } /** * Retrieve the <code>String</code> value of this object. */ public synchronized String toString() { return stringValue; } /** * For serialization, write this object in a 1.7 compatible manner. This * adds the extra <code>useBoolean</code> flag that 1.7 needs. When * deserialized, the <code>defaultReadObject</code> method will do the right * thing. * * @param stream * the output stream to write this object to */ private void writeObject(ObjectOutputStream stream) throws IOException { ObjectOutputStream.PutField fields = stream.putFields(); fields.put("stringValue", stringValue); fields.put("booleanValue", booleanValue); // Synthesize this property for 1.7 compatibility fields.put("useBoolean", (booleanValue == false)); stream.writeFields(); } /** * Tests this object for equality with the given object. * * @param o * the object to be compared against * @return <code>true</code> if the object is equal, otherwise * <code>false</code> */ public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof SimpleScalar)) { return false; } final SimpleScalar simpleScalar = (SimpleScalar) o; if (booleanValue != simpleScalar.booleanValue) { return false; } if (stringValue == null) { return simpleScalar.stringValue == null; } return stringValue.equals(simpleScalar.stringValue); } /** * Return the hash value for this object. * * @return a hash code corresponding to the value of this SimpleScalar */ public int hashCode() { int result; result = (stringValue != null ? stringValue.hashCode() : 0); result = 29 * result + (booleanValue ? 1 : 0); return result; } }