org.sakaiproject.metaobj.shared.model.ElementBean.java Source code

Java tutorial

Introduction

Here is the source code for org.sakaiproject.metaobj.shared.model.ElementBean.java

Source

/**********************************************************************************
 * $URL: https://source.sakaiproject.org/svn/metaobj/trunk/metaobj-api/api/src/java/org/sakaiproject/metaobj/shared/model/ElementBean.java $
 * $Id: ElementBean.java 105079 2012-02-24 23:08:11Z ottenhoff@longsight.com $
 ***********************************************************************************
 *
 * Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009 The Sakai Foundation
 *
 * Licensed under the Educational Community License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.opensource.org/licenses/ECL-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 **********************************************************************************/

package org.sakaiproject.metaobj.shared.model;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom.Attribute;
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.sakaiproject.component.cover.ComponentManager;
import org.sakaiproject.metaobj.shared.mgt.FieldValueWrapperFactory;
import org.sakaiproject.metaobj.utils.TypedMap;
import org.sakaiproject.metaobj.utils.mvc.intf.FieldValueWrapper;
import org.sakaiproject.metaobj.utils.xml.NormalizationException;
import org.sakaiproject.metaobj.utils.xml.SchemaNode;

/**
 * Created by IntelliJ IDEA.
 * User: John Ellis
 * Date: Mar 10, 2004
 * Time: 3:45:39 PM
 * To change this template use File | Settings | File Templates.
 */
public class ElementBean extends HashMap implements TypedMap {

    protected final Log logger = LogFactory.getLog(getClass());

    private Element baseElement;
    private Map types = new HashMap();
    private SchemaNode currentSchema;
    private Map wrappedInstances = new HashMap();
    private Map wrappedLists = new HashMap();
    private boolean deferValidation = true;
    private ElementListBean parent;

    public static final String FIELD_DATA_TAG = "FIELD_DATA";

    private static FieldValueWrapperFactory wrapperFactory = null;

    public ElementBean(String elementName, SchemaNode currentSchema) {
        this.currentSchema = currentSchema;
        setBaseElement(new Element(elementName));
    }

    public ElementBean(String elementName, SchemaNode currentSchema, boolean deferValidation) {
        this.deferValidation = deferValidation;
        this.currentSchema = currentSchema;
        setBaseElement(new Element(elementName));
    }

    public ElementBean() {
        setBaseElement(new Element("empty"));
    }

    public ElementBean(Element baseElement, SchemaNode currentSchema, boolean deferValidation) {
        this.deferValidation = deferValidation;
        this.currentSchema = currentSchema;
        setBaseElement(baseElement);
    }

    public ElementBean(Element baseElement, SchemaNode currentSchema, Map wrappedInstances) {
        this.currentSchema = currentSchema;
        this.wrappedInstances = wrappedInstances;
        setBaseElement(baseElement);
    }

    public Element currentElement() {
        return baseElement;
    }

    public SchemaNode getCurrentSchema() {
        return currentSchema;
    }

    public void setCurrentSchema(SchemaNode currentSchema) {
        this.currentSchema = currentSchema;
    }

    public Object put(Object key, Object value) {
        if (currentSchema == null) {
            logger.debug("null schema -- ignore put for " + key);
            return null;
        }

        SchemaNode elementSchema = currentSchema.getChild((String) key);

        if (getWrapperFactory().checkWrapper(elementSchema.getObjectType())) {
            return this.wrappedObjectPut(key, value, elementSchema);
        }

        if (elementSchema.getMaxOccurs() == 1) {

            String normalizedValue;

            try {
                normalizedValue = elementSchema.getSchemaNormalizedValue(value);
            } catch (NormalizationException exp) {
                if (deferValidation) {
                    normalizedValue = value.toString();
                } else {
                    throw exp;
                }
            }

            if (elementSchema.isAttribute()) {
                Attribute oldAttribute = currentElement().getAttribute((String) key);
                if (value != null && value.toString().length() > 0) {
                    logger.debug("not removing attribute" + key);
                    if (oldAttribute == null) {
                        currentElement().setAttribute(key.toString(), normalizedValue);
                    } else {
                        oldAttribute.setValue(normalizedValue);
                    }
                } else if (oldAttribute != null) {
                    logger.debug("removing attribute" + key);
                    currentElement().removeAttribute(key.toString());
                }
            } else {
                Element oldElement = currentElement().getChild((String) key);

                if (value != null && value.toString().length() > 0) {
                    if (oldElement == null) {
                        Element newElement = new Element((String) key);
                        newElement.addContent(normalizedValue);
                        currentElement().addContent(newElement);
                    } else {
                        oldElement.setText(normalizedValue);
                    }
                } else if (oldElement != null) {
                    currentElement().removeContent(oldElement);
                }
            }
        } else {
            // if you got here, must be a simple element
            ElementListBean listBean = (ElementListBean) get(key);

            while (listBean.size() > 0) {
                listBean.remove(0);
            }

            if (value instanceof String[]) {

                String[] values = (String[]) value;

                for (int i = 0; i < values.length; i++) {
                    if (values[i].length() > 0) {
                        ElementBean bean = listBean.createBlank();
                        bean.getBaseElement().addContent(values[i]);
                        listBean.add(bean);
                    }
                }
            } else if (value instanceof String) {
                if (value.toString().length() > 0) {
                    ElementBean bean = listBean.createBlank();
                    bean.getBaseElement().addContent((String) value);
                    listBean.add(bean);
                }
            }

        }

        return null;
    }

    protected FieldValueWrapperFactory getWrapperFactory() {
        if (wrapperFactory == null) {
            wrapperFactory = (FieldValueWrapperFactory) ComponentManager.getInstance()
                    .get("fieldValueWrapperFactory");
        }
        return wrapperFactory;
    }

    public static void setWrapperFactory(FieldValueWrapperFactory wrapperFactory) {
        ElementBean.wrapperFactory = wrapperFactory;
    }

    public Object remove(Object key) {
        currentElement().removeChild((String) key);
        types.remove(key);
        return null;
    }

    public Object get(Object key) {
        if (currentSchema == null) {
            logger.debug("null schema -- ignore get for " + key);
            return null;
        }

        SchemaNode schema = currentSchema.getChild((String) key);

        if (schema == null) {
            return null;
        }

        if (schema.getMaxOccurs() > 1 || schema.getMaxOccurs() == -1) {
            List childElements = new ArrayList();
            List rawElements = baseElement.getChildren((String) key);
            for (Iterator i = rawElements.iterator(); i.hasNext();) {
                logger.debug("got child");
                childElements.add(new ElementBean((Element) i.next(), schema, deferValidation));
            }

            if (getWrapperFactory().checkWrapper(schema.getObjectType())) {
                return wrappedListGet(childElements, schema, key);
            } else {
                return new ElementListBean(baseElement, childElements, schema, deferValidation);
            }
        }

        if (getWrapperFactory().checkWrapper(schema.getObjectType())) {
            return this.wrappedObjectGet(key, schema);
        }

        if (schema.isAttribute()) {
            Attribute child = baseElement.getAttribute((String) key);

            if (child == null) {
                return null;
            } else {
                try {
                    return schema.getActualNormalizedValue(child.getValue());
                } catch (NormalizationException exp) {
                    // This should not happen... values should already be validated...
                    // just return the text itself...
                    return child.getValue();
                }
            }
        } else {
            Element child = baseElement.getChild((String) key);

            if (child == null) {
                if (schema.getObjectType().isAssignableFrom(java.util.Map.class)) {
                    child = new Element(schema.getName());
                    baseElement.addContent(child);
                } else {
                    return null;
                }
            }

            logger.debug("returning typed object");

            Class objectClass = schema.getObjectType();

            if (Map.class.isAssignableFrom(objectClass)) {
                return new ElementBean(child, schema, deferValidation);
            } else {
                try {
                    return schema.getActualNormalizedValue(child.getText());
                } catch (NormalizationException exp) {
                    // This should not happen... values should already be validated...
                    // just return the text itself...
                    return child.getText();
                }
            }
        }
    }

    protected Object wrappedListGet(List childElements, SchemaNode schema, Object key) {
        if (wrappedLists.get(key) == null) {
            wrappedLists.put(key,
                    new ElementListBeanWrapper(
                            new ElementListBean(baseElement, childElements, schema, deferValidation),
                            (FieldValueWrapper) wrappedObjectGet(key, schema)));
        }

        return wrappedLists.get(key);
    }

    protected Object wrappedObjectPut(Object key, Object value, SchemaNode schema) {
        FieldValueWrapper wrapper = (FieldValueWrapper) wrappedInstances.get(key);

        if (wrapper == null) {
            wrapper = getWrapperFactory().wrapInstance(value);
            wrappedInstances.put(key, wrapper);
        } else {
            wrapper.setValue(value);
        }

        Element childElement = getBaseElement().getChild(schema.getName());

        if (childElement == null) {
            childElement = new Element(schema.getName());
            getBaseElement().addContent(childElement);
        }

        childElement.setText(schema.getSchemaNormalizedValue(value));

        return null;
    }

    protected Object wrappedObjectGet(Object key, SchemaNode schema) {
        FieldValueWrapper wrapper = (FieldValueWrapper) wrappedInstances.get(key);

        if (wrapper == null) {
            wrapper = getWrapperFactory().wrapInstance(schema.getObjectType());
            wrappedInstances.put(key, wrapper);

            Element valueElement = getBaseElement().getChild(schema.getName());

            if (valueElement != null && valueElement.getContentSize() != 0) {
                Object value = schema.getActualNormalizedValue(valueElement.getText());
                wrapper.setValue(value);
            }
        }

        return wrapper;
    }

    public Class getType(String key) {
        if (currentSchema == null) {
            logger.debug("null schema -- ignore getType for " + key);
            return null;
        }

        SchemaNode schema = currentSchema.getChild(key);

        if (schema != null) {
            if (schema.getMaxOccurs() > 1 || schema.getMaxOccurs() == -1) {
                if (getWrapperFactory().checkWrapper(schema.getObjectType())) {
                    return ElementListBeanWrapper.class;
                } else {
                    return ElementListBean.class;
                }
            } else {
                return schema.getObjectType();
            }
        }
        return null;
    }

    public String toString() {
        return currentElement().getText();
    }

    public void setBaseElement(Element element) {
        this.baseElement = element;
    }

    public Element getBaseElement() {
        return baseElement;
    }

    public boolean isDeferValidation() {
        return deferValidation;
    }

    public void setDeferValidation(boolean deferValidation) {
        this.deferValidation = deferValidation;
    }

    /**
     * Generate a string containing XML tags and values representing the current contents of the element
     *
     * @return An XML String representation of the object
     */
    public String toXmlString() throws PersistenceException {
        XMLOutputter outputter = new XMLOutputter();
        ByteArrayOutputStream os = new ByteArrayOutputStream();

        try {
            Format format = Format.getPrettyFormat();
            outputter.setFormat(format);
            outputter.output(getBaseElement(), os);
            return new String(os.toByteArray());
            //return os.toByteArray();
        } catch (IOException e) {
            throw new PersistenceException(e, "Unable to write object", null, null);
        }

    } // toXmlString

    class EntrySet implements Map.Entry {

        private Object key;
        private Object value;
        //TODO what about equals and hashcode?

        public EntrySet(Object key, Object value) {
            this.key = key;
            this.value = value;
        }

        /* (non-Javadoc)
         * @see java.util.Map.Entry#getKey()
         */
        public Object getKey() {
            return key;
        }

        /* (non-Javadoc)
         * @see java.util.Map.Entry#getValue()
         */
        public Object getValue() {
            return value;
        }

        /* (non-Javadoc)
         * @see java.util.Map.Entry#setValue(java.lang.Object)
         */
        public Object setValue(Object value) {
            // TODO Maybe throw an exception instead
            this.value = value;
            return this.value;
        }

    }

    /* (non-Javadoc)
     * @see java.util.Map#entrySet()
     */
    public Set entrySet() {
        Set entries = new HashSet();

        if (currentSchema == null) {
            logger.debug("null schema -- ignore entrySet");
            return entries;
        }

        List children = currentSchema.getChildren();
        for (Iterator iter = children.iterator(); iter.hasNext();) {
            SchemaNode child = (SchemaNode) iter.next();
            String key = child.getName();
            Object value = get(key);
            EntrySet entry = new EntrySet(key, value);
            entries.add(entry);
        }

        return entries;
    }

    /* (non-Javadoc)
     * @see java.util.Map#keySet()
     */
    public Set keySet() {
        Set keys = new HashSet();
        for (Iterator iter = entrySet().iterator(); iter.hasNext();) {
            EntrySet child = (EntrySet) iter.next();
            keys.add(child.getKey());
        }
        return keys;
    }

    /* (non-Javadoc)
     * @see java.util.Map#values()
     */
    public Collection values() {
        Set values = new HashSet();
        for (Iterator iter = entrySet().iterator(); iter.hasNext();) {
            EntrySet child = (EntrySet) iter.next();
            Object value = child.getValue();
            values.add(value);
        }
        return values;
    }

    public ElementListBean getParent() {
        return parent;
    }

    public void setParent(ElementListBean parent) {
        this.parent = parent;
    }

    public int getIndex() {
        if (parent != null) {
            return getParent().indexOf(this);
        }
        return 0;
    }

}