/*
* DocumentProperty.java
*
* This work is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* This work 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 for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* Copyright (c) 2004 Per Cederberg. All rights reserved.
*/
package org.liquidsite.core.content;
/**
* A document property container. This class defines the meta-data
* for a document property, but not the property value itself.
*
* @author Per Cederberg, <per at percederberg dot net>
* @version 1.0
*/
public class DocumentProperty implements Comparable {
/**
* The string type constant. The string type represents document
* properties that are input using a simple HTML input field,
* i.e. a string without newlines.
*/
public static final int STRING_TYPE = 1;
/**
* The tagged type constant. The tagged type represents document
* properties that are input using a textarea HTML input field
* and contains special tags for formatting.
*/
public static final int TAGGED_TYPE = 2;
/**
* The HTML type constant. The HTML type represents document
* properties that are input using an HTML editor field, i.e. a
* string containing HTML markup.
*/
public static final int HTML_TYPE = 3;
/**
* The unique document property identifier.
*/
private String id = "";
/**
* The document property name. The name is used for presenting
* the property for the user.
*/
private String name = "";
/**
* The document property position.
*/
private int position = 0;
/**
* The document property type.
*/
private int type = STRING_TYPE;
/**
* The document property description.
*/
private String description = "";
/**
* Creates a new document property.
*
* @param id the document property identifier
*/
public DocumentProperty(String id) {
this.id = id;
}
/**
* Creates a document property from an XML-encoded string with
* values.
*
* @param id the document property identifier
* @param xml the XML-encoded property values
*/
DocumentProperty(String id, String xml) {
this.id = id;
decodeXml(xml);
}
/**
* Compares this object to another object. The comparison will
* only work with other document property objects, and will
* compare the position numbers.
*
* @param obj the object to compare with
*
* @return less than zero (0) if this object is previous,
* zero if the objects are equal, or
* greater than zero otherwise
*
* @throws ClassCastException if the specified object wasn't a
* document property
*/
public int compareTo(Object obj) throws ClassCastException {
DocumentProperty prop = (DocumentProperty) obj;
int diff = position - prop.position;
if (diff == 0) {
return name.compareTo(prop.name);
} else {
return diff;
}
}
/**
* Returns the unique document property identifier.
*
* @return the unique document property identifier
*/
public String getId() {
return id;
}
/**
* Returns the document property name.
*
* @return the document property name
*/
public String getName() {
return name;
}
/**
* Sets the document property name.
*
* @param name the new name
*/
public void setName(String name) {
this.name = name;
}
/**
* Returns the document property position.
*
* @return the document property position
*/
public int getPosition() {
return position;
}
/**
* Sets the document property position.
*
* @param position the new position
*/
public void setPosition(int position) {
this.position = position;
}
/**
* Returns the document property type.
*
* @return the document property type
*
* @see #STRING_TYPE
* @see #TAGGED_TYPE
* @see #HTML_TYPE
*/
public int getType() {
return type;
}
/**
* Sets the document property type.
*
* @param type the new type
*
* @see #STRING_TYPE
* @see #TAGGED_TYPE
* @see #HTML_TYPE
*/
public void setType(int type) {
this.type = type;
}
/**
* Returns the document property description.
*
* @return the document property description
*/
public String getDescription() {
return description;
}
/**
* Sets the document property description.
*
* @param description the new description
*/
public void setDescription(String description) {
this.description = description;
}
/**
* Encodes all the values in the document property to an XML
* string.
*
* @return the XML-encoded property values
*/
public String encodeXml() {
StringBuffer buffer = new StringBuffer();
buffer.append("<property id='");
buffer.append(encodeXmlData(id));
buffer.append("'>");
buffer.append("<name>");
buffer.append(encodeXmlData(name));
buffer.append("</name>");
buffer.append("<position>");
buffer.append(position);
buffer.append("</position>");
buffer.append("<type>");
buffer.append(type);
buffer.append("</type>");
buffer.append("<description>");
buffer.append(encodeXmlData(description));
buffer.append("</description>");
buffer.append("</property>");
return buffer.toString();
}
/**
* Decodes all the values in the document property from an XML
* string.
*
* @param xml the XML-encoded property values
*/
private void decodeXml(String xml) {
String tag;
String tagName;
String tagAttributes;
int pos;
while (xml.length() > 0) {
pos = xml.indexOf("<");
if (pos < 0) {
break;
}
xml = xml.substring(pos + 1);
pos = xml.indexOf(">");
tag = xml.substring(0, pos);
xml = xml.substring(pos + 1);
pos = tag.indexOf(" ");
if (pos < 0) {
tagName = tag;
tagAttributes = "";
} else {
tagName = tag.substring(0, pos);
tagAttributes = tag.substring(pos + 1);
}
pos = xml.indexOf("</" + tagName);
decodeXmlTag(tagName, tagAttributes, xml.substring(0, pos));
pos = xml.indexOf(">", pos);
xml = xml.substring(pos + 1);
}
}
/**
* Decodes an XML tag.
*
* @param tag the XML tag name
* @param attributes the encoded attribute string
* @param data the encoded data string
*/
private void decodeXmlTag(String tag,
String attributes,
String data) {
if (tag.equals("name")) {
name = decodeXmlData(data);
} else if (tag.equals("position")) {
position = Integer.parseInt(data);
} else if (tag.equals("type")) {
type = Integer.parseInt(data);
} else if (tag.equals("description")) {
description = decodeXmlData(data);
} else {
decodeXml(data);
}
}
/**
* Encodes a string as an XML data string. This will escape any
* occurencies of special XML characters.
*
* @param str the string to encode
*
* @return the XML-encoded data string
*/
private String encodeXmlData(String str) {
StringBuffer buffer = new StringBuffer();
char c;
for (int i = 0; i < str.length(); i++) {
c = str.charAt(i);
if (c == '<') {
buffer.append("<");
} else if (c == '>') {
buffer.append(">");
} else if (c == '&') {
buffer.append("&");
} else if (c == '"') {
buffer.append(""");
} else if (c == '\'') {
buffer.append("'");
} else {
buffer.append(c);
}
}
return buffer.toString();
}
/**
* Decodes an XML data string to a normal string. This will
* unescape any occurencies of special XML entities.
*
* @param str the string to decode
*
* @return the unencoded data string
*/
private String decodeXmlData(String str) {
StringBuffer buffer = new StringBuffer();
while (str.length() > 0) {
if (str.startsWith("<")) {
buffer.append("<");
str = str.substring(4);
} else if (str.startsWith(">")) {
buffer.append(">");
str = str.substring(4);
} else if (str.startsWith("&")) {
buffer.append("&");
str = str.substring(5);
} else if (str.startsWith(""")) {
buffer.append("\"");
str = str.substring(6);
} else if (str.startsWith("'")) {
buffer.append("'");
str = str.substring(6);
} else {
buffer.append(str.charAt(0));
str = str.substring(1);
}
}
return buffer.toString();
}
}