All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opencms.acacia.shared.CmsEntity Maven / Gradle / Ivy

Go to download

OpenCms is an enterprise-ready, easy to use website content management system based on Java and XML technology. Offering a complete set of features, OpenCms helps content managers worldwide to create and maintain beautiful websites fast and efficiently.

There is a newer version: 18.0
Show newest version
/*
 * This library is part of OpenCms -
 * the Open Source Content Management System
 *
 * Copyright (C) Alkacon Software (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 org.opencms.acacia.shared;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.google.common.collect.Lists;
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.HandlerRegistration;
import com.google.gwt.event.shared.SimpleEventBus;

/**
 * Serializable entity implementation.

*/ public class CmsEntity implements HasValueChangeHandlers, Serializable { /** * Handles child entity changes.

*/ protected class EntityChangeHandler implements ValueChangeHandler { /** * @see com.google.gwt.event.logical.shared.ValueChangeHandler#onValueChange(com.google.gwt.event.logical.shared.ValueChangeEvent) */ public void onValueChange(ValueChangeEvent event) { fireChange(); } } /** The serial version id. */ private static final long serialVersionUID = -6933931178070025267L; /** The entity attribute values. */ private Map> m_entityAttributes; /** The entity id. */ private String m_id; /** The simple attribute values. */ private Map> m_simpleAttributes; /** The type name. */ private String m_typeName; /** The event bus. */ private transient SimpleEventBus m_eventBus; /** The child entites change handler. */ private transient EntityChangeHandler m_childChangeHandler = new EntityChangeHandler(); /** The handler registrations. */ private transient Map m_changeHandlerRegistry; /** * Constructor.

* * @param id the entity id/URI * @param typeName the entity type name */ public CmsEntity(String id, String typeName) { this(); m_id = id; m_typeName = typeName; } /** * Constructor. For serialization only.

*/ protected CmsEntity() { m_simpleAttributes = new HashMap>(); m_entityAttributes = new HashMap>(); m_changeHandlerRegistry = new HashMap(); } /** * Returns the value of a simple attribute for the given path or null, if the value does not exist.

* * @param entity the entity to get the value from * @param pathElements the path elements * * @return the value */ public static String getValueForPath(CmsEntity entity, String[] pathElements) { String result = null; if ((pathElements != null) && (pathElements.length >= 1)) { String attributeName = pathElements[0]; int index = CmsContentDefinition.extractIndex(attributeName); if (index > 0) { index--; } attributeName = entity.getTypeName() + "/" + CmsContentDefinition.removeIndex(attributeName); CmsEntityAttribute attribute = entity.getAttribute(attributeName); if (!((attribute == null) || (attribute.isComplexValue() && (pathElements.length == 1)))) { if (attribute.isSimpleValue()) { if ((pathElements.length == 1) && (attribute.getValueCount() > 0)) { List values = attribute.getSimpleValues(); result = values.get(index); } } else if (attribute.getValueCount() > (index)) { String[] childPathElements = new String[pathElements.length - 1]; for (int i = 1; i < pathElements.length; i++) { childPathElements[i - 1] = pathElements[i]; } List values = attribute.getComplexValues(); result = getValueForPath(values.get(index), childPathElements); } } } return result; } /** * Gets the list of values reachable from the given base object with the given path.

* * @param baseObject the base object (a CmsEntity or a string) * @param pathComponents the path components * @return the list of values for the given path (either of type String or CmsEntity) */ public static List getValuesForPath(Object baseObject, String[] pathComponents) { List currentList = Lists.newArrayList(); currentList.add(baseObject); for (String pathComponent : pathComponents) { List newList = Lists.newArrayList(); for (Object element : currentList) { newList.addAll(getValuesForPathComponent(element, pathComponent)); } currentList = newList; } return currentList; } /** * Gets the values reachable from a given object (an entity or a string) with a single XPath component.

* * If entityOrString is a string, and pathComponent is "VALUE", a list containing only entityOrString is returned. * Otherwise, entityOrString is assumed to be an entity, and the pathComponent is interpreted as a field of the entity * (possibly with an index). * * @param entityOrString the entity or string from which to get the values for the given path component * @param pathComponent the path component * @return the list of reachable values */ public static List getValuesForPathComponent(Object entityOrString, String pathComponent) { List result = Lists.newArrayList(); if (pathComponent.equals("VALUE")) { result.add(entityOrString); } else { if (entityOrString instanceof CmsEntity) { CmsEntity entity = (CmsEntity)entityOrString; boolean hasIndex = CmsContentDefinition.hasIndex(pathComponent); int index = CmsContentDefinition.extractIndex(pathComponent); if (index > 0) { index--; } String attributeName = entity.getTypeName() + "/" + CmsContentDefinition.removeIndex(pathComponent); CmsEntityAttribute attribute = entity.getAttribute(attributeName); if (attribute != null) { if (hasIndex) { if (index < attribute.getValueCount()) { if (attribute.isSimpleValue()) { result.add(attribute.getSimpleValues().get(index)); } else { result.add(attribute.getComplexValues().get(index)); } } } else { if (attribute.isSimpleValue()) { result.addAll(attribute.getSimpleValues()); } else { result.addAll(attribute.getComplexValues()); } } } } } return result; } /** * Adds the given attribute value.

* * @param attributeName the attribute name * @param value the attribute value */ public void addAttributeValue(String attributeName, CmsEntity value) { if (m_simpleAttributes.containsKey(attributeName)) { throw new RuntimeException("Attribute already exists with a simple type value."); } if (m_entityAttributes.containsKey(attributeName)) { m_entityAttributes.get(attributeName).add(value); } else { List values = new ArrayList(); values.add(value); m_entityAttributes.put(attributeName, values); } registerChangeHandler(value); fireChange(); } /** * Adds the given attribute value.

* * @param attributeName the attribute name * @param value the attribute value */ public void addAttributeValue(String attributeName, String value) { if (m_entityAttributes.containsKey(attributeName)) { throw new RuntimeException("Attribute already exists with a entity type value."); } if (m_simpleAttributes.containsKey(attributeName)) { m_simpleAttributes.get(attributeName).add(value); } else { List values = new ArrayList(); values.add(value); m_simpleAttributes.put(attributeName, values); } fireChange(); } /** * @see com.google.gwt.event.logical.shared.HasValueChangeHandlers#addValueChangeHandler(com.google.gwt.event.logical.shared.ValueChangeHandler) */ public HandlerRegistration addValueChangeHandler(ValueChangeHandler handler) { return addHandler(handler, ValueChangeEvent.getType()); } /** * Clones the given entity keeping all entity ids.

* * @return returns the cloned instance */ public CmsEntity cloneEntity() { CmsEntity clone = new CmsEntity(getId(), getTypeName()); for (CmsEntityAttribute attribute : getAttributes()) { if (attribute.isSimpleValue()) { List values = attribute.getSimpleValues(); for (String value : values) { clone.addAttributeValue(attribute.getAttributeName(), value); } } else { List values = attribute.getComplexValues(); for (CmsEntity value : values) { clone.addAttributeValue(attribute.getAttributeName(), value.cloneEntity()); } } } return clone; } /** * Creates a deep copy of this entity.

* * @param entityId the id of the new entity, if null a generic id will be used * * @return the entity copy */ public CmsEntity createDeepCopy(String entityId) { CmsEntity result = new CmsEntity(entityId, getTypeName()); for (CmsEntityAttribute attribute : getAttributes()) { if (attribute.isSimpleValue()) { List values = attribute.getSimpleValues(); for (String value : values) { result.addAttributeValue(attribute.getAttributeName(), value); } } else { List values = attribute.getComplexValues(); for (CmsEntity value : values) { result.addAttributeValue(attribute.getAttributeName(), value.createDeepCopy(null)); } } } return result; } /** * Ensures that the change event is also fired on child entity change.

*/ public void ensureChangeHandlers() { if (!m_changeHandlerRegistry.isEmpty()) { for (HandlerRegistration reg : m_changeHandlerRegistry.values()) { reg.removeHandler(); } m_changeHandlerRegistry.clear(); } for (List attr : m_entityAttributes.values()) { for (CmsEntity child : attr) { registerChangeHandler(child); child.ensureChangeHandlers(); } } } /** * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { boolean result = false; if (obj instanceof CmsEntity) { CmsEntity test = (CmsEntity)obj; if (m_simpleAttributes.keySet().equals(test.m_simpleAttributes.keySet()) && m_entityAttributes.keySet().equals(test.m_entityAttributes.keySet())) { result = true; for (String attributeName : m_simpleAttributes.keySet()) { if (!m_simpleAttributes.get(attributeName).equals(test.m_simpleAttributes.get(attributeName))) { result = false; break; } } if (result) { for (String attributeName : m_entityAttributes.keySet()) { if (!m_entityAttributes.get(attributeName).equals(test.m_entityAttributes.get(attributeName))) { result = false; break; } } } } } return result; } /** * @see com.google.gwt.event.shared.HasHandlers#fireEvent(com.google.gwt.event.shared.GwtEvent) */ public void fireEvent(GwtEvent event) { ensureHandlers().fireEventFromSource(event, this); } /** * Returns an attribute.

* * @param attributeName the attribute name * * @return the attribute value */ public CmsEntityAttribute getAttribute(String attributeName) { if (m_simpleAttributes.containsKey(attributeName)) { return CmsEntityAttribute.createSimpleAttribute(attributeName, m_simpleAttributes.get(attributeName)); } if (m_entityAttributes.containsKey(attributeName)) { return CmsEntityAttribute.createEntityAttribute(attributeName, m_entityAttributes.get(attributeName)); } return null; } /** * Returns all entity attributes.

* * @return the entity attributes */ public List getAttributes() { List result = new ArrayList(); for (String name : m_simpleAttributes.keySet()) { result.add(getAttribute(name)); } for (String name : m_entityAttributes.keySet()) { result.add(getAttribute(name)); } return result; } /** * Returns this or a child entity with the given id.

* Will return null if no entity with the given id is present.

* * @param entityId the entity id * * @return the entity */ public CmsEntity getEntityById(String entityId) { CmsEntity result = null; if (m_id.equals(entityId)) { result = this; } else { for (List children : m_entityAttributes.values()) { for (CmsEntity child : children) { result = child.getEntityById(entityId); if (result != null) { break; } } if (result != null) { break; } } } return result; } /** * Returns the entity id.

* * @return the id */ public String getId() { return m_id; } /** * Returns the entity type name.

* * @return the entity type name */ public String getTypeName() { return m_typeName; } /** * Returns if the entity has the given attribute.

* * @param attributeName the attribute name * * @return true if the entity has the given attribute */ public boolean hasAttribute(String attributeName) { return m_simpleAttributes.containsKey(attributeName) || m_entityAttributes.containsKey(attributeName); } /** * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return super.hashCode(); } /** * Inserts a new attribute value at the given index.

* * @param attributeName the attribute name * @param value the attribute value * @param index the value index */ public void insertAttributeValue(String attributeName, CmsEntity value, int index) { if (m_entityAttributes.containsKey(attributeName)) { m_entityAttributes.get(attributeName).add(index, value); } else { setAttributeValue(attributeName, value); } registerChangeHandler(value); fireChange(); } /** * Inserts a new attribute value at the given index.

* * @param attributeName the attribute name * @param value the attribute value * @param index the value index */ public void insertAttributeValue(String attributeName, String value, int index) { if (m_simpleAttributes.containsKey(attributeName)) { m_simpleAttributes.get(attributeName).add(index, value); } else { setAttributeValue(attributeName, value); } fireChange(); } /** * Removes the given attribute.

* * @param attributeName the attribute name */ public void removeAttribute(String attributeName) { removeAttributeSilent(attributeName); fireChange(); } /** * Removes the attribute without triggering any change events.

* * @param attributeName the attribute name */ public void removeAttributeSilent(String attributeName) { CmsEntityAttribute attr = getAttribute(attributeName); if (attr != null) { if (attr.isSimpleValue()) { m_simpleAttributes.remove(attributeName); } else { for (CmsEntity child : attr.getComplexValues()) { removeChildChangeHandler(child); } m_entityAttributes.remove(attributeName); } } } /** * Removes a specific attribute value.

* * @param attributeName the attribute name * @param index the value index */ public void removeAttributeValue(String attributeName, int index) { if (m_simpleAttributes.containsKey(attributeName)) { List values = m_simpleAttributes.get(attributeName); if ((values.size() == 1) && (index == 0)) { removeAttributeSilent(attributeName); } else { values.remove(index); } } else if (m_entityAttributes.containsKey(attributeName)) { List values = m_entityAttributes.get(attributeName); if ((values.size() == 1) && (index == 0)) { removeAttributeSilent(attributeName); } else { CmsEntity child = values.remove(index); removeChildChangeHandler(child); } } fireChange(); } /** * Sets the given attribute value. Will remove all previous attribute values.

* * @param attributeName the attribute name * @param value the attribute value */ public void setAttributeValue(String attributeName, CmsEntity value) { // make sure there is no attribute value set removeAttributeSilent(attributeName); addAttributeValue(attributeName, value); } /** * Sets the given attribute value at the given index.

* * @param attributeName the attribute name * @param value the attribute value * @param index the value index */ public void setAttributeValue(String attributeName, CmsEntity value, int index) { if (m_simpleAttributes.containsKey(attributeName)) { throw new RuntimeException("Attribute already exists with a simple type value."); } if (!m_entityAttributes.containsKey(attributeName)) { if (index != 0) { throw new IndexOutOfBoundsException(); } else { addAttributeValue(attributeName, value); } } else { if (m_entityAttributes.get(attributeName).size() > index) { CmsEntity child = m_entityAttributes.get(attributeName).remove(index); removeChildChangeHandler(child); } m_entityAttributes.get(attributeName).add(index, value); fireChange(); } } /** * Sets the given attribute value. Will remove all previous attribute values.

* * @param attributeName the attribute name * @param value the attribute value */ public void setAttributeValue(String attributeName, String value) { m_entityAttributes.remove(attributeName); List values = new ArrayList(); values.add(value); m_simpleAttributes.put(attributeName, values); fireChange(); } /** * Sets the given attribute value at the given index.

* * @param attributeName the attribute name * @param value the attribute value * @param index the value index */ public void setAttributeValue(String attributeName, String value, int index) { if (m_entityAttributes.containsKey(attributeName)) { throw new RuntimeException("Attribute already exists with a simple type value."); } if (!m_simpleAttributes.containsKey(attributeName)) { if (index != 0) { throw new IndexOutOfBoundsException(); } else { addAttributeValue(attributeName, value); } } else { if (m_simpleAttributes.get(attributeName).size() > index) { m_simpleAttributes.get(attributeName).remove(index); } m_simpleAttributes.get(attributeName).add(index, value); fireChange(); } } /** * Returns the JSON string representation of this entity.

* * @return the JSON string representation of this entity */ public String toJSON() { StringBuffer result = new StringBuffer(); result.append("{\n"); for (Entry> simpleEntry : m_simpleAttributes.entrySet()) { result.append("\"").append(simpleEntry.getKey()).append("\"").append(": [\n"); boolean firstValue = true; for (String value : simpleEntry.getValue()) { if (firstValue) { firstValue = false; } else { result.append(",\n"); } result.append("\"").append(value).append("\""); } result.append("],\n"); } for (Entry> entityEntry : m_entityAttributes.entrySet()) { result.append("\"").append(entityEntry.getKey()).append("\"").append(": [\n"); boolean firstValue = true; for (CmsEntity value : entityEntry.getValue()) { if (firstValue) { firstValue = false; } else { result.append(",\n"); } result.append(value.toJSON()); } result.append("],\n"); } result.append("\"id\": \"").append(m_id).append("\""); result.append("}"); return result.toString(); } /** * @see java.lang.Object#toString() */ @Override public String toString() { return toJSON(); } /** * Adds this handler to the widget. * * @param the type of handler to add * @param type the event type * @param handler the handler * @return {@link HandlerRegistration} used to remove the handler */ protected final HandlerRegistration addHandler(final H handler, GwtEvent.Type type) { return ensureHandlers().addHandlerToSource(type, this, handler); } /** * Fires the change event for this entity.

*/ void fireChange() { ValueChangeEvent.fire(this, this); } /** * Lazy initializing the handler manager.

* * @return the handler manager */ private SimpleEventBus ensureHandlers() { if (m_eventBus == null) { m_eventBus = new SimpleEventBus(); } return m_eventBus; } /** * Adds the value change handler to the given entity.

* * @param child the child entity */ private void registerChangeHandler(CmsEntity child) { HandlerRegistration reg = child.addValueChangeHandler(m_childChangeHandler); m_changeHandlerRegistry.put(child.getId(), reg); } /** * Removes the child entity change handler.

* * @param child the child entity */ private void removeChildChangeHandler(CmsEntity child) { HandlerRegistration reg = m_changeHandlerRegistry.remove(child.getId()); if (reg != null) { reg.removeHandler(); } } }