com.alkacon.vie.client.Entity.java Source code

Java tutorial

Introduction

Here is the source code for com.alkacon.vie.client.Entity.java

Source

/*
 * This library is part of OpenCms -
 * the Open Source Content Management System
 *
 * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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
 * Lesser General Public License for more details.
 *
 * For further information about Alkacon Software, please see the
 * company website: http://www.alkacon.com
 *
 * For further information about OpenCms, please see the
 * project website: http://www.opencms.org
 * 
 * You should have received a copy of the GNU Lesser 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 com.alkacon.vie.client;

import com.alkacon.vie.shared.I_Entity;
import com.alkacon.vie.shared.I_EntityAttribute;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.event.logical.shared.HasValueChangeHandlers;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.event.shared.HandlerRegistration;

/**
 * The entity wrapper.<p>
 */
public final class Entity extends JavaScriptObject implements HasValueChangeHandlers<Entity>, I_Entity {

    /** Place holder value for empty strings. */
    // HACK: this place holder is only used because the current native VIE implementation does
    // not support empty strings as values
    private static final String EMPTY_STRING = "########empty-string########";

    /**
     * Constructor, for internal use only.<p>
     */
    protected Entity() {

    }

    /**
     * Helper method for firing a 'value changed' event.<p>
     *
     * @param entity the entity that changed
     */
    private static void fireValueChangedEvent(Entity entity) {

        ValueChangeEvent.fire(entity, entity);
    }

    /**
     * @see com.alkacon.vie.shared.I_Entity#addAttributeValue(java.lang.String, com.alkacon.vie.shared.I_Entity)
     */
    public void addAttributeValue(String attributeName, I_Entity value) {

        internalAddAttributeValue(attributeName, value);
        registerChange((Entity) value);
    }

    /**
     * @see com.alkacon.vie.shared.I_Entity#addAttributeValue(java.lang.String, java.lang.String)
     */
    public native void addAttributeValue(String attributeName, String value) /*-{
                                                                             if (value == "") {
                                                                             value = @com.alkacon.vie.client.Entity::EMPTY_STRING;
                                                                             }
                                                                             this
                                                                             .setOrAdd(
                                                                             @com.alkacon.vie.client.Vie::addPointyBrackets(Ljava/lang/String;)(attributeName),
                                                                             value);
                                                                             }-*/;

    /**
     * Adds this handler to the widget.
     *
     * @param <H> the type of handler to add
     * @param type the event type
     * @param handler the handler
     * 
     * @return {@link HandlerRegistration} used to remove the handler
     */
    public <H extends EventHandler> HandlerRegistration addHandler(final H handler, GwtEvent.Type<H> type) {

        return ensureHandlers().addHandler(type, handler);
    }

    /**
     * @see com.google.gwt.event.logical.shared.HasValueChangeHandlers#addValueChangeHandler(com.google.gwt.event.logical.shared.ValueChangeHandler)
     */
    public HandlerRegistration addValueChangeHandler(ValueChangeHandler<Entity> handler) {

        return addHandler(handler, ValueChangeEvent.getType());
    }

    /**
     * @see com.alkacon.vie.shared.I_Entity#createDeepCopy(java.lang.String)
     */
    public I_Entity createDeepCopy(String entityId) {

        I_Entity result = Vie.getInstance().createEntity(entityId, getTypeName());
        for (I_EntityAttribute attribute : getAttributes()) {
            if (attribute.isSimpleValue()) {
                List<String> values = attribute.getSimpleValues();
                for (String value : values) {
                    result.addAttributeValue(attribute.getAttributeName(), value);
                }
            } else {
                List<I_Entity> values = attribute.getComplexValues();
                for (I_Entity value : values) {
                    I_Entity valueCopy = ((Entity) value).createDeepCopy(null);
                    result.addAttributeValue(attribute.getAttributeName(), valueCopy);
                }
            }
        }
        return result;
    }

    /**
     * @see com.google.gwt.event.shared.HasHandlers#fireEvent(com.google.gwt.event.shared.GwtEvent)
     */
    public void fireEvent(GwtEvent<?> event) {

        if (getHandlerManager() != null) {
            getHandlerManager().fireEvent(event);
        }

    }

    /**
     * @see com.alkacon.vie.shared.I_Entity#getAttribute(java.lang.String)
     */
    public I_EntityAttribute getAttribute(String attributeName) {

        String internaltAttributeName = Vie.addPointyBrackets(attributeName);
        if (!hasAttribute(internaltAttributeName)) {
            return null;
        }
        if (isSimpleAttribute(internaltAttributeName)) {
            return new EntityAttribute(attributeName, getSimpleValues(internaltAttributeName));
        }
        return new EntityAttribute(attributeName, getComplexValues(internaltAttributeName));
    }

    /**
     * @see com.alkacon.vie.shared.I_Entity#getAttributes()
     */
    public List<I_EntityAttribute> getAttributes() {

        List<I_EntityAttribute> result = new ArrayList<I_EntityAttribute>();
        JsArrayString attributeNames = getAttributeNames();
        for (int i = 0; i < attributeNames.length(); i++) {
            I_EntityAttribute attribute = getAttribute(attributeNames.get(i));
            if (attribute != null) {
                result.add(attribute);
            }
        }
        return result;
    }

    /**
     * @see com.alkacon.vie.shared.I_Entity#getId()
     */
    public native String getId() /*-{
                                 try {
                                 var subject = this.getSubject();
                                 } catch (error) {
                                 console.log(error);
                                 }
                                 subject = @com.alkacon.vie.client.Vie::removePointyBrackets(Ljava/lang/String;)(subject);
                                 return subject;
                                 }-*/;

    /**
     * @see com.alkacon.vie.shared.I_Entity#getTypeName()
     */
    public native String getTypeName() /*-{
                                           
                                       var type = this.get('@type');
                                       var result = (typeof type === 'string') ? type : type.id;
                                       return @com.alkacon.vie.client.Vie::removePointyBrackets(Ljava/lang/String;)(result);
                                       }-*/;

    /**
     * @see com.alkacon.vie.shared.I_Entity#hasAttribute(java.lang.String)
     */
    public native boolean hasAttribute(String attributeName) /*-{
                                                                 
                                                             return this
                                                             .has(@com.alkacon.vie.client.Vie::addPointyBrackets(Ljava/lang/String;)(attributeName));
                                                             }-*/;

    /**
     * Returns if the entity has the given type.<p>
     *
     * @param type the type
     *
     * @return <code>true</code> if the entity has the given type
     */
    public native boolean hasType(String type) /*-{
                                                   
                                               return this
                                               .hasType(@com.alkacon.vie.client.Vie::addPointyBrackets(Ljava/lang/String;)(type));
                                               }-*/;

    /**
     * @see com.alkacon.vie.shared.I_Entity#insertAttributeValue(java.lang.String, com.alkacon.vie.shared.I_Entity, int)
     */
    public void insertAttributeValue(String attributeName, I_Entity value, int index) {

        I_EntityAttribute attribute = getAttribute(attributeName);
        if (index < 0) {
            throw new IndexOutOfBoundsException("Index should be > 0");
        }
        if ((attribute == null) && (index > 0)) {
            throw new IndexOutOfBoundsException("Index of " + index + " to big.");
        }
        if (attribute == null) {
            setAttributeValue(attributeName, value);
        } else {
            List<I_Entity> values = attribute.getComplexValues();
            if (index > values.size()) {
                throw new IndexOutOfBoundsException("Index of " + index + " to big.");
            }
            if (index == values.size()) {
                addAttributeValue(attributeName, value);
            } else {
                removeAttributeSilent(attributeName);
                for (int i = 0; i < values.size(); i++) {
                    if (i == index) {
                        addAttributeValue(attributeName, value);
                    }
                    addAttributeValue(attributeName, values.get(i));

                }
            }
        }
    }

    /**
     * @see com.alkacon.vie.shared.I_Entity#insertAttributeValue(java.lang.String, java.lang.String, int)
     */
    public void insertAttributeValue(String attributeName, String value, int index) {

        I_EntityAttribute attribute = getAttribute(attributeName);
        if (index < 0) {
            throw new IndexOutOfBoundsException("Index should be > 0");
        }
        if ((attribute == null) && (index > 0)) {
            throw new IndexOutOfBoundsException("Index of " + index + " to big.");
        }
        if (attribute == null) {
            setAttributeValue(attributeName, value);
        } else {
            List<String> values = attribute.getSimpleValues();
            if (index > values.size()) {
                throw new IndexOutOfBoundsException("Index of " + index + " to big.");
            }
            if (index == values.size()) {
                addAttributeValue(attributeName, value);
            } else {
                removeAttributeSilent(attributeName);
                for (int i = 0; i < values.size(); i++) {
                    if (i == index) {
                        addAttributeValue(attributeName, value);
                    }
                    addAttributeValue(attributeName, values.get(i));

                }
            }
        }
    }

    /**
     * Removes the given attribute.<p>
     *
     * @param attributeName the attribute name
     */
    public native void removeAttribute(String attributeName) /*-{
                                                                 
                                                             this
                                                             .unset(@com.alkacon.vie.client.Vie::addPointyBrackets(Ljava/lang/String;)(attributeName));
                                                             }-*/;

    /**
     * @see com.alkacon.vie.shared.I_Entity#removeAttributeSilent(java.lang.String)
     */
    public native void removeAttributeSilent(String attributeName) /*-{
                                                                       
                                                                   this
                                                                   .unset(
                                                                   @com.alkacon.vie.client.Vie::addPointyBrackets(Ljava/lang/String;)(attributeName),
                                                                   {
                                                                   silent : true
                                                                   });
                                                                   }-*/;

    /**
     * @see com.alkacon.vie.shared.I_Entity#removeAttributeValue(java.lang.String, int)
     */
    public void removeAttributeValue(String attributeName, int index) {

        if (!hasAttribute(attributeName)) {
            return;
        }
        I_EntityAttribute attribute = getAttribute(attributeName);
        if (attribute.isSingleValue() && (index == 0)) {
            removeAttribute(attributeName);
        } else {
            removeAttributeSilent(attributeName);
            if (attribute.isSimpleValue()) {
                for (int i = 0; i < attribute.getSimpleValues().size(); i++) {
                    if (i != index) {
                        addAttributeValue(attributeName, attribute.getSimpleValues().get(i));
                    }
                }

            } else {
                for (int i = 0; i < attribute.getComplexValues().size(); i++) {
                    if (i != index) {
                        addAttributeValue(attributeName, attribute.getComplexValues().get(i));
                    }
                }
            }
        }
    }

    /**
     * @see com.alkacon.vie.shared.I_Entity#setAttributeValue(java.lang.String, com.alkacon.vie.shared.I_Entity)
     */
    public void setAttributeValue(String attributeName, I_Entity value) {

        internalSetAttributeValue(attributeName, value);
        registerChange((Entity) value);
    }

    /**
     * @see com.alkacon.vie.shared.I_Entity#setAttributeValue(java.lang.String, com.alkacon.vie.shared.I_Entity, int)
     */
    public void setAttributeValue(String attributeName, I_Entity value, int index) {

        if (!(value instanceof Entity)) {
            throw new UnsupportedOperationException("May only set native entities as values.");
        }
        if ((index == 0) && !hasAttribute(attributeName)) {
            setAttributeValue(attributeName, value);
        }
        I_EntityAttribute attribute = getAttribute(attributeName);
        if ((index == 0) && attribute.isSingleValue()) {
            setAttributeValue(attributeName, value);
        } else {
            List<I_Entity> values = attribute.getComplexValues();
            if (index >= values.size()) {
                throw new IndexOutOfBoundsException("Index of " + index + " to big.");
            }
            removeAttributeSilent(attributeName);
            for (int i = 0; i < values.size(); i++) {
                if (i == index) {
                    addAttributeValue(attributeName, value);
                } else {
                    addAttributeValue(attributeName, values.get(i));
                }
            }
        }

    }

    /**
     * @see com.alkacon.vie.shared.I_Entity#setAttributeValue(java.lang.String, java.lang.String)
     */
    public native void setAttributeValue(String attributeName, String value) /*-{
                                                                             if (value == "") {
                                                                             value = @com.alkacon.vie.client.Entity::EMPTY_STRING;
                                                                             }
                                                                             attributeName = @com.alkacon.vie.client.Vie::addPointyBrackets(Ljava/lang/String;)(attributeName);
                                                                             this.unset(attributeName, {
                                                                             silent : true
                                                                             });
                                                                             this.setOrAdd(attributeName, value);
                                                                             }-*/;

    /**
     * @see com.alkacon.vie.shared.I_Entity#setAttributeValue(java.lang.String, java.lang.String, int)
     */
    public void setAttributeValue(String attributeName, String value, int index) {

        I_EntityAttribute attribute = getAttribute(attributeName);
        if ((attribute == null) || ((index == 0) && attribute.isSingleValue())) {
            setAttributeValue(attributeName, value);
        } else {
            List<String> values = attribute.getSimpleValues();
            if (index >= values.size()) {
                throw new IndexOutOfBoundsException("Index of " + index + " to big.");
            }
            removeAttributeSilent(attributeName);
            for (int i = 0; i < values.size(); i++) {
                if (i == index) {
                    addAttributeValue(attributeName, value);
                } else {
                    addAttributeValue(attributeName, values.get(i));
                }
            }
        }
    }

    /**
     * @see com.alkacon.vie.shared.I_Entity#toJSON()
     */
    public native String toJSON() /*-{
                                      
                                  return JSON.stringify(this);
                                  }-*/;

    /**
     * Sets the entity changed, triggering the value changed event.<p>
     */
    protected native void setChanged() /*-{
                                       this.change();
                                       }-*/;

    /**
     * Binds the {@link #com.alkacon.vie.client.Entity.fireValueChangedEvent(Entity)} method 
     * to the native change function and sets the handler manager for this instance.<p>
     *
     * @param handlerManager the handler manager to use
     */
    private native void bindChange(HandlerManager handlerManager)/*-{
                                                                     
                                                                 this.handlerManager = handlerManager;
                                                                 var self = this;
                                                                 this
                                                                 .bind(
                                                                 "change",
                                                                 function() {
                                                                 @com.alkacon.vie.client.Entity::fireValueChangedEvent(Lcom/alkacon/vie/client/Entity;)(self);
                                                                 });
                                                                 }-*/;

    /**
     * Ensures the existence of the handler manager.
     *
     * @return the handler manager
     * */
    private HandlerManager ensureHandlers() {

        if (getHandlerManager() == null) {
            bindChange(new HandlerManager(this));
        }
        return getHandlerManager();
    }

    /**
     * Returns the names of the available attributes.<p>
     * 
     * @return the attribute names
     */
    private native JsArrayString getAttributeNames() /*-{
                                                     var names = new Array();
                                                     var attributes = this.attributes;
                                                     for ( var key in attributes) {
                                                     names
                                                     .push(@com.alkacon.vie.client.Vie::removePointyBrackets(Ljava/lang/String;)(key));
                                                     }
                                                     return names;
                                                     }-*/;

    /**
     * Returns the values of the given attribute as an array of entities.<p>
     * Check if the given attribute is of complex type first!!<p>
     * 
     * @param attributeName the name of the attribute 
     * 
     * @return the attribute values
     */
    private native I_EntityCollection getComplexValues(String attributeName) /*-{
                                                                                 
                                                                             var attr = this.get(attributeName);
                                                                             return attr;
                                                                             }-*/;

    /**
     * Returns the handler manager.<p>
     *
     * @return the handler manager
     */
    private native HandlerManager getHandlerManager()/*-{
                                                         
                                                     return this.handlerManager;
                                                     }-*/;

    /**
     * Returns the values of the given attribute as an array of entities.<p>
     * Check if the given attribute is of complex type first!!<p>
     * 
     * @param attributeName the name of the attribute 
     * 
     * @return the attribute values
     */
    private native JsArrayString getSimpleValues(String attributeName) /*-{
                                                                           
                                                                       var attr = this.get(attributeName);
                                                                       if (typeof attr === 'string') {
                                                                       attr = [ attr ];
                                                                       }
                                                                       if (attr != null) {
                                                                       for ( var i = 0; i < attr.length; i++) {
                                                                       if (attr[i] == @com.alkacon.vie.client.Entity::EMPTY_STRING) {
                                                                       attr[i] = "";
                                                                       }
                                                                       }
                                                                       }
                                                                       return attr;
                                                                       }-*/;

    /**
     * Internal method to add a complex attribute value.<p>
     * 
     * @param attributeName the attribute name
     * @param value the value
     */
    private native void internalAddAttributeValue(String attributeName, I_Entity value) /*-{
                                                                                        this
                                                                                        .setOrAdd(
                                                                                        @com.alkacon.vie.client.Vie::addPointyBrackets(Ljava/lang/String;)(attributeName),
                                                                                        value);
                                                                                        }-*/;

    /**
     * Internal method to set a complex attribute value.<p>
     * 
     * @param attributeName the attribute name
     * @param value the value
     */
    private native void internalSetAttributeValue(String attributeName, I_Entity value) /*-{
                                                                                        attributeName = @com.alkacon.vie.client.Vie::addPointyBrackets(Ljava/lang/String;)(attributeName);
                                                                                        this.unset(attributeName, {
                                                                                        silent : true
                                                                                        });
                                                                                        this.set(attributeName, value);
                                                                                        }-*/;

    /**
     * Returns if the given attribute is of the simple type.<p>
     * 
     * @param attributeName the name of the attribute
     * 
     * @return <code>true</code> is this is a simple type attribute
     */
    private native boolean isSimpleAttribute(String attributeName) /*-{
                                                                       
                                                                   var attr = this.get(attributeName);
                                                                   if (typeof attr === 'string') {
                                                                   return true;
                                                                   }
                                                                   if (attr.isEntity) {
                                                                   return false;
                                                                   }
                                                                   if (Object.prototype.toString.call(attr) === '[object Array]') {
                                                                   if (typeof attr[0] === 'string') {
                                                                   return true;
                                                                   }
                                                                   }
                                                                   return false;
                                                                   }-*/;

    /**
     * Registers the change event of the new child to trigger change on this entity.<p>
     * 
     * @param child the child to register
     */
    private native void registerChange(Entity child) /*-{
                                                     var self = this;
                                                     child.bind("change", function() {
                                                     self.change();
                                                     });
                                                     }-*/;
}