package org.openedit.xml;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import org.dom4j.Attribute;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.Text;
import org.openedit.MultiValued;
import org.openedit.data.SaveableData;
import com.openedit.OpenEditException;
public class ElementData implements MultiValued, SaveableData, Comparable
{
protected Element fieldElement;
protected String fieldSourcePath;
protected String fieldVersion;
protected static final Pattern INVALIDSTUFF = Pattern.compile("[\'\"\n<>&]");
public String getVersion() {
return fieldVersion;
}
public void setVersion(String inVersion) {
fieldVersion = inVersion;
}
public ElementData()
{
}
public ElementData(Element inEl)
{
setElement(inEl);
}
public ElementData(Object inEl)
{
setElement((Element)inEl);
}
public Element getElement()
{
if (fieldElement == null)
{
fieldElement = DocumentHelper.createElement("element");
}
return fieldElement;
}
public void setElement(Element inElement)
{
fieldElement = inElement;
}
/**
* First we try the child node in case we have CDATA
* Then we try the attributes
*/
public String get(String inId)
{
Element child = getElement().element(inId);
if( child != null)
{
return child.getText();
}
if( inId.equals("name"))
{
String name = getElement().attributeValue(inId);
if( name == null)
{
name =getElement().getText();
}
return name;
} else if(inId.equals(".version")){
return getVersion();//elastic search
}
else if( inId.equals("sourcepath"))
{
return getSourcePath();
}
return getElement().attributeValue(inId);
}
public float getFloat(String inId)
{
String val = get(inId);
if( val != null)
{
return Float.parseFloat(val);
}
return 0;
}
public String getId()
{
return getElement().attributeValue("id");
}
public String getName()
{
return toString();
}
public void setName(String inName)
{
setProperty("name",inName);
}
public void setId(String inNewid)
{
getElement().addAttribute("id",inNewid);
}
public void setProperty(String inId, String inValue)
{
if(inId.equals(".version"))
{
setVersion(inValue);
}
else
{
//synchronized (getElement()) //TODO: Remove this now that we have proper locking?
//{
if( inId.equals("name"))
{
for (Iterator iterator = getElement().nodeIterator(); iterator.hasNext();)
{
Node type = (Node) iterator.next();
if( type instanceof Text)
{
getElement().remove(type);
break;
}
}
}
//always check for a child
Element child = getElement().element(inId);
if( child != null)
{
//TODO: See if value changed?
getElement().remove(child);
}
if( inValue == null || inValue.length() == 0)
{
Attribute attr = getElement().attribute(inId);
if( attr != null)
{
getElement().remove(attr);
}
}
else
{
if( INVALIDSTUFF.matcher(inValue).find() )
{
Attribute attr = getElement().attribute(inId);
if( attr != null)
{
getElement().remove(attr);
}
getElement().addElement(inId).addCDATA(inValue);
}
else
{
getElement().addAttribute(inId,inValue);
}
}
//}
}
}
public String getSourcePath()
{
return fieldSourcePath;
}
public void setSourcePath(String inSourcepath)
{
fieldSourcePath = inSourcepath;
}
public Map getProperties()
{
Map all = new HashMap();
//all.put("name", getName()); //would this cause problems when saving?
for (Iterator iterator = getAttributes().iterator(); iterator.hasNext();)
{
org.dom4j.Attribute attr = (org.dom4j.Attribute) iterator.next();
all.put(attr.getName(),attr.getValue() );
}
for (Iterator iterator = getElement().elementIterator(); iterator.hasNext();)
{
Element child = (Element) iterator.next();
all.put(child.getName(),child.getText());
}
return all;
}
public List getAttributes()
{
return getElement().attributes();
}
public int compareTo(Object inO)
{
return toString().compareTo(inO.toString());
}
public String toString()
{
String name = get("name");
if( name == null)
{
name = getId();
}
if( name == null)
{
name = super.toString();
}
return name;
}
public void setProperties(Map<String,String> inProperties)
{
//getProperties().putAll(inProperties);
for (Iterator iterator = inProperties.keySet().iterator(); iterator.hasNext();)
{
String key = (String) iterator.next();
if( key != null)
{
setProperty(key,inProperties.get(key));
}
}
}
public Collection<String> getValues(String inPreference)
{
String val = get(inPreference);
if (val == null)
return null;
String[] vals = null;
if( val.contains("|") )
{
vals = VALUEDELMITER.split(val);
}
else
{
vals = val.split("\\s+"); //legacy
}
Collection collection = Arrays.asList(vals);
//if null check parent
return collection;
}
public void setValues(String inKey, Collection<String> inValues)
{
StringBuffer values = new StringBuffer();
for (Iterator iterator = inValues.iterator(); iterator.hasNext();)
{
String detail = (String) iterator.next();
values.append(detail);
if( iterator.hasNext())
{
values.append(" | ");
}
}
setProperty(inKey,values.toString());
}
public Object clone()
{
try
{
return super.clone();
}
catch ( Exception ex )
{
throw new OpenEditException(ex);
}
}
}