/*
* 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.plugins.jacms.aps.system.services.content.model.extraAttribute;
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.attribute.AbstractJAXBAttribute;
import com.agiletec.aps.system.common.entity.model.attribute.TextAttribute;
import com.agiletec.aps.system.services.baseconfig.ConfigInterface;
import com.agiletec.aps.system.services.group.Group;
import com.agiletec.aps.system.services.lang.Lang;
import com.agiletec.plugins.jacms.aps.system.JacmsSystemConstants;
import com.agiletec.plugins.jacms.aps.system.services.content.model.CmsAttributeReference;
import com.agiletec.plugins.jacms.aps.system.services.content.model.Content;
import com.agiletec.plugins.jacms.aps.system.services.content.model.extraAttribute.util.ICmsAttributeErrorCodes;
import com.agiletec.plugins.jacms.aps.system.services.resource.IResourceManager;
import com.agiletec.plugins.jacms.aps.system.services.resource.model.ResourceInterface;
/**
* Classe astratta di appoggio agli attributi di tipo Risorsa.
* @author E.Santoboni
*/
public abstract class AbstractResourceAttribute extends TextAttribute
implements IReferenceableAttribute, ResourceAttributeInterface {
private static final Logger _logger = LoggerFactory.getLogger(AbstractResourceAttribute.class);
@Override
public Object getAttributePrototype() {
AbstractResourceAttribute prototype = (AbstractResourceAttribute) super.getAttributePrototype();
prototype.setConfigManager(this.getConfigManager());
prototype.setResourceManager(this.getResourceManager());
return prototype;
}
/**
* Setta una risorsa sull'attributo.
* @param resource La risorsa da associare all'attributo.
* @param langCode il codice della lingua.
*/
@Override
public void setResource(ResourceInterface resource, String langCode) {
if (null == langCode) {
langCode = this.getDefaultLangCode();
}
if (null == resource) {
this.getResources().remove(langCode);
} else {
this.getResources().put(langCode, resource);
}
}
/**
* Restituisce la risorsa associata all'attributo.
* @param langCode il codice della lingua.
* @return la risorsa associata all'attributo.
*/
@Override
public ResourceInterface getResource(String langCode) {
return (ResourceInterface) this.getResources().get(langCode);
}
/**
* Restituisce la risorsa associata all'attributo.
* @return la risorsa associata all'attributo.
*/
@Override
public ResourceInterface getResource() {
ResourceInterface res = this.getResource(this.getRenderingLang());
if (null == res) {
res = this.getResource(this.getDefaultLangCode());
}
return res;
}
/**
* Sovrascrittura del metodo della classe astratta da cui deriva. Poichè
* questo tipo di attributo non può mai essere "searchable", restituisce sempre false.
* @return Restituisce sempre false
* @see com.agiletec.aps.system.common.entity.model.attribute.AttributeInterface#isSearchable()
*/
@Override
public boolean isSearchable() {
return false;
}
@Override
public boolean isSearchableOptionSupported() {
return false;
}
@Override
public Element getJDOMElement() {
Element attributeElement = this.createRootElement("attribute");
Iterator<String> langIter = this.getResources().keySet().iterator();
while (langIter.hasNext()) {
String currentLangCode = (String) langIter.next();
ResourceInterface res = this.getResource(currentLangCode);
if (null != res) {
Element resourceElement = new Element("resource");
resourceElement.setAttribute("resourcetype", res.getType());
String resourceId = String.valueOf(res.getId());
resourceElement.setAttribute("id", resourceId);
resourceElement.setAttribute("lang", currentLangCode);
attributeElement.addContent(resourceElement);
}
}
super.addTextElements(attributeElement);
return attributeElement;
}
/**
* Appende, nella stringa rappresentante l'url della risorsa interna ad un entità,
* il riferimento al entità padre con la sintassi
* <baseUrl>/<REFERENCED_RESOURCE_INDICATOR>/<PARENT_CONTENT_ID>/.
* Tale operazione viene effettuata nel caso che la risorsa non sia libera.
* @param basePath Il path base della risorsa.
* @return Il path corretto.
*/
protected String appendContentReference(String basePath) {
ResourceInterface res = this.getResource();
if (null == res) {
return "";
}
String resourceGroup = res.getMainGroup();
if (!Group.FREE_GROUP_NAME.equals(resourceGroup)
&& !this.getParentEntity().getGroups().isEmpty()) {
if (!basePath.endsWith("/")) {
basePath += "/";
}
basePath += REFERENCED_RESOURCE_INDICATOR
+ "/" + this.getParentEntity().getId() + "/";
}
return basePath;
}
@Override
public List<CmsAttributeReference> getReferences(List<Lang> systemLangs) {
List<CmsAttributeReference> refs = new ArrayList<CmsAttributeReference>();
for (int i = 0; i < systemLangs.size(); i++) {
Lang lang = systemLangs.get(i);
ResourceInterface res = this.getResource(lang.getCode());
if (null != res) {
CmsAttributeReference ref = new CmsAttributeReference(null, null, res.getId());
refs.add(ref);
}
}
return refs;
}
@Override
public Object getValue() {
if (null == this.getResources() || this.getResources().isEmpty()) {
return null;
}
return this.getResources();
}
@Override
protected AbstractJAXBAttribute getJAXBAttributeInstance() {
return new JAXBResourceAttribute();
}
@Override
public AbstractJAXBAttribute getJAXBAttribute(String langCode) {
JAXBResourceAttribute jaxbResourceAttribute = (JAXBResourceAttribute) super.createJAXBAttribute(langCode);
if (null == jaxbResourceAttribute) return null;
if (null == langCode) {
langCode = this.getDefaultLangCode();
}
ResourceInterface resource = this.getResource(langCode);
if (null == resource) {
return jaxbResourceAttribute;
}
JAXBResourceValue value = new JAXBResourceValue();
try {
String text = this.getTextForLang(langCode);
value.setText(text);
this.setRenderingLang(langCode);
String path = this.getDefaultPath();
value.setPath(path);
value.setResourceId(resource.getId());
StringBuilder restResourcePath = new StringBuilder();
restResourcePath.append(this.getConfigManager().getParam("applicationBaseURL"));
restResourcePath.append("api/rs/").append(langCode).append("/jacms/");
if (this.getType().equals(JacmsSystemConstants.RESOURE_ATTACH_CODE)) {
restResourcePath.append("attachment");
} else {
restResourcePath.append("image");
}
restResourcePath.append("?id=").append(resource.getId());
value.setRestResourcePath(restResourcePath.toString());
} catch (Throwable t) {
_logger.error("Error creating jaxb response. lang: {}", langCode, t);
throw new RuntimeException("Error creating jaxb response", t);
}
jaxbResourceAttribute.setResource(value);
return jaxbResourceAttribute;
}
@Override
public void valueFrom(AbstractJAXBAttribute jaxbAttribute) {
super.valueFrom(jaxbAttribute);
JAXBResourceValue value = ((JAXBResourceAttribute) jaxbAttribute).getResource();
if (null == value) {
return;
}
Object resourceId = value.getResourceId();
if (null == resourceId) {
return;
}
try {
IResourceManager resourceManager = this.getResourceManager();
ResourceInterface resource = resourceManager.loadResource(resourceId.toString());
if (null != resource) {
this.setResource(resource, this.getDefaultLangCode());
}
Object text = value.getText();
if (null == text) {
return;
}
this.getTextMap().put(this.getDefaultLangCode(), text.toString());
} catch (Exception e) {
_logger.error("Error extracting resource from jaxbAttribute", e);
}
}
@Override
public Status getStatus() {
Status textStatus = super.getStatus();
Status resourceStatus = (null != this.getResource()) ? Status.VALUED : Status.EMPTY;
if (!textStatus.equals(resourceStatus)) {
return Status.INCOMPLETE;
}
if (textStatus.equals(resourceStatus) && textStatus.equals(Status.VALUED)) {
return Status.VALUED;
}
return Status.EMPTY;
}
protected abstract String getDefaultPath();
public Map<String, ResourceInterface> getResources() {
return this._resources;
}
@Override
public List<AttributeFieldError> validate(AttributeTracer tracer) {
List<AttributeFieldError> errors = super.validate(tracer);
try {
if (null == this.getResources()) {
return errors;
}
List<Lang> langs = super.getLangManager().getLangs();
for (int i = 0; i < langs.size(); i++) {
Lang lang = langs.get(i);
ResourceInterface resource = this.getResource(lang.getCode());
if (null == resource) {
continue;
}
AttributeTracer resourceTracer = (AttributeTracer) tracer.clone();
resourceTracer.setLang(lang);
String resourceMainGroup = resource.getMainGroup();
Content parentContent = (Content) this.getParentEntity();
if (!resourceMainGroup.equals(Group.FREE_GROUP_NAME)
&& !resourceMainGroup.equals(parentContent.getMainGroup())
&& !parentContent.getGroups().contains(resourceMainGroup)) {
AttributeFieldError fieldError = new AttributeFieldError(this, ICmsAttributeErrorCodes.INVALID_RESOURCE_GROUPS, resourceTracer);
fieldError.setMessage("Invalid resource group - " + resourceMainGroup);
errors.add(fieldError);
}
}
} catch (Throwable t) {
_logger.error("Error validating text attribute", t);
throw new RuntimeException("Error validating text attribute", t);
}
return errors;
}
protected ConfigInterface getConfigManager() {
return _configManager;
}
public void setConfigManager(ConfigInterface configManager) {
this._configManager = configManager;
}
protected IResourceManager getResourceManager() {
return _resourceManager;
}
public void setResourceManager(IResourceManager resourceManager) {
this._resourceManager = resourceManager;
}
private Map<String, ResourceInterface> _resources = new HashMap<String, ResourceInterface>();
public static final String REFERENCED_RESOURCE_INDICATOR = "ref";
private ConfigInterface _configManager;
private IResourceManager _resourceManager;
}