/* * Copyright 2015-Present Entando Inc. (http://www.entando.com) All rights reserved. * * 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. */ package com.agiletec.aps.system.common.entity.model.attribute; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.jdom.Element; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.agiletec.aps.system.common.entity.model.AttributeFieldError; import com.agiletec.aps.system.common.entity.model.AttributeTracer; import com.agiletec.aps.system.common.entity.model.FieldError; import com.agiletec.aps.system.services.lang.Lang; /** * This class represents the Attribute of type "Multi-language List", composed by several * homogeneous attributes; there is a list for every language in the system. * @author M.Diana */ public class ListAttribute extends AbstractListAttribute { private static final Logger _logger = LoggerFactory.getLogger(ListAttribute.class); /** * Initialize the data structure. */ public ListAttribute() { this._listMap = new HashMap<String, List<AttributeInterface>>(); } /** * Add a new empty attribute to the list in the specified language. * @param langCode The code of the language. * @return The attribute added to the list, ready to be populated with the data. */ public AttributeInterface addAttribute(String langCode) { AttributeInterface newAttr = (AttributeInterface) this.getNestedAttributeType().getAttributePrototype(); newAttr.setDefaultLangCode(this.getDefaultLangCode()); newAttr.setParentEntity(this.getParentEntity()); List<AttributeInterface> attrList = this.getAttributeList(langCode); attrList.add(newAttr); return newAttr; } /** * Return the list of attributes of the desired language. * @param langCode The language code. * @return A list of homogeneous attributes. */ public List<AttributeInterface> getAttributeList(String langCode) { List<AttributeInterface> attrList = (List<AttributeInterface>) this._listMap.get(langCode); if (attrList == null) { attrList = new ArrayList<AttributeInterface>(); this._listMap.put(langCode, attrList); } return attrList; } /** * Return the list of attributes in the current rendering language. * @return A list of homogeneous attributes. */ @Override public Object getRenderingAttributes() { List<AttributeInterface> attrList = this.getAttributeList(this.getRenderingLang()); return attrList; } /** * Remove from the list one of the attributes of the given language. * @param langCode The code of the language of the list where to delete the attribute from. * @param index The index of the attribute in the list. */ public void removeAttribute(String langCode, int index) { List<AttributeInterface> attrList = this.getAttributeList(langCode); attrList.remove(index); if (attrList.isEmpty()) { this._listMap.remove(langCode); } } @Override public void setDefaultLangCode(String langCode) { super.setDefaultLangCode(langCode); Iterator<List<AttributeInterface>> values = this._listMap.values().iterator(); while (values.hasNext()) { List<AttributeInterface> elementList = values.next(); Iterator<AttributeInterface> attributes = elementList.iterator(); while (attributes.hasNext()) { AttributeInterface attribute = attributes.next(); attribute.setDefaultLangCode(langCode); } } } @Override public Element getJDOMElement() { Element listElement = this.createRootElement("list"); listElement.setAttribute("nestedtype", this.getNestedAttributeTypeCode()); Iterator<String> langIter = _listMap.keySet().iterator(); while (langIter.hasNext()) { String langCode = langIter.next(); Element listLangElement = new Element("listlang"); if (null != langCode) { listLangElement.setAttribute("lang", langCode); List<AttributeInterface> attributeList = this.getAttributeList(langCode); Iterator<AttributeInterface> attributeListIter = attributeList.iterator(); while (attributeListIter.hasNext()) { AttributeInterface attribute = attributeListIter.next(); Element attributeElement = attribute.getJDOMElement(); listLangElement.addContent(attributeElement); } listElement.addContent(listLangElement); } } return listElement; } /** * Return a Map containing all the localized versions of the associated list. * @return A map indexed by the language code. */ public Map<String, List<AttributeInterface>> getAttributeListMap() { return _listMap; } @Override public List<AttributeInterface> getAttributes() { List<AttributeInterface> attributes = new ArrayList<AttributeInterface>(); Iterator<List<AttributeInterface>> values = this.getAttributeListMap().values().iterator(); while (values.hasNext()) { attributes.addAll(values.next()); } return attributes; } @Override public Object getValue() { return this.getAttributeListMap(); } @Override public AbstractJAXBAttribute getJAXBAttribute(String langCode) { JAXBListAttribute jaxbAttribute = (JAXBListAttribute) super.createJAXBAttribute(langCode); if (null == jaxbAttribute) return null; List<AttributeInterface> attributes = this.getAttributeList(langCode); if (null == attributes) { return null; } List<AbstractJAXBAttribute> jaxbList = this.extractJAXBListAttributes(attributes, langCode); jaxbAttribute.setAttributes(jaxbList); return jaxbAttribute; } @Override public void valueFrom(AbstractJAXBAttribute jaxbAttribute) { super.valueFrom(jaxbAttribute); JAXBListAttribute jaxbListAttribute = (JAXBListAttribute) jaxbAttribute; if (null == jaxbListAttribute) return; List<AbstractJAXBAttribute> attributes = jaxbListAttribute.getAttributes(); if (null == attributes) return; for (int i = 0; i < attributes.size(); i++) { AbstractJAXBAttribute jaxbAttributeElement = attributes.get(i); AttributeInterface attribute = this.addAttribute(this.getDefaultLangCode()); attribute.valueFrom(jaxbAttributeElement); } } @Override public Status getStatus() { Lang defaultLang = super.getLangManager().getDefaultLang(); List<AttributeInterface> attributeList = this.getAttributeList(defaultLang.getCode()); boolean valued = (null != attributeList && !attributeList.isEmpty()); if (valued) { return Status.VALUED; } else { return Status.EMPTY; } } @Override public List<AttributeFieldError> validate(AttributeTracer tracer) { List<AttributeFieldError> errors = super.validate(tracer); try { List<Lang> langs = super.getLangManager().getLangs(); for (int i = 0; i < langs.size(); i++) { Lang lang = langs.get(i); List<AttributeInterface> attributeList = this.getAttributeList(lang.getCode()); for (int j = 0; j < attributeList.size(); j++) { AttributeInterface attributeElement = attributeList.get(j); AttributeTracer elementTracer = (AttributeTracer) tracer.clone(); elementTracer.setListElement(true); elementTracer.setListLang(lang); elementTracer.setListIndex(j); Status elementStatus = attributeElement.getStatus(); if (elementStatus.equals(Status.EMPTY)) { errors.add(new AttributeFieldError(attributeElement, FieldError.INVALID, elementTracer)); } else { List<AttributeFieldError> elementErrors = attributeElement.validate(elementTracer); if (null != elementErrors) { errors.addAll(elementErrors); } } } } } catch (Throwable t) { //ApsSystemUtils.logThrowable(t, this, "validate"); _logger.error("Error validating list attribute", t); throw new RuntimeException("Error validating list attribute", t); } return errors; } private Map<String, List<AttributeInterface>> _listMap; }