/* * Copyright (C) 2005-2012 BetaCONCEPT Limited * * This file is part of Astroboa. * * Astroboa 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 3 of the License, or * (at your option) any later version. * * Astroboa 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. * * You should have received a copy of the GNU Lesser General Public License * along with Astroboa. If not, see <http://www.gnu.org/licenses/>. */ package org.betaconceptframework.astroboa.model.impl; import java.io.Serializable; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.betaconceptframework.astroboa.api.model.CmsProperty; import org.betaconceptframework.astroboa.api.model.ComplexCmsProperty; import org.betaconceptframework.astroboa.api.model.ValueType; import org.betaconceptframework.astroboa.api.model.definition.CmsPropertyDefinition; import org.betaconceptframework.astroboa.api.model.definition.ComplexCmsPropertyDefinition; import org.betaconceptframework.astroboa.api.model.definition.Localization; import org.betaconceptframework.astroboa.api.model.exception.CmsException; import org.betaconceptframework.astroboa.api.model.exception.MultipleOccurenceException; import org.betaconceptframework.astroboa.api.model.exception.SingleOccurenceException; import org.betaconceptframework.astroboa.util.CmsConstants; import org.betaconceptframework.astroboa.util.PropertyPath; /** * @author Gregory Chomatas (gchomatas@betaconcept.com) * @author Savvas Triantafyllou (striantafyllou@betaconcept.com) * */ public abstract class CmsPropertyImpl<D extends CmsPropertyDefinition, P extends ComplexCmsProperty<? extends ComplexCmsPropertyDefinition, ? extends ComplexCmsProperty<?,?>>> extends LocalizableEntityImpl implements CmsProperty<D,P>, Serializable { /** * */ private static final long serialVersionUID = -2241602551059154622L; protected String name; private P parentProperty; private String fullPath; private String path; private String fullPermanentPath; private String permanentPath; //It is used to keep the full definition path of this property so that // its property definition can be restored during deserialization //The value on this variable is set in setPropertyDefinition method protected String fullPropertyDefinitionPath; protected transient D propertyDefinition; public D getPropertyDefinition() { return propertyDefinition; } public void setPropertyDefinition(D propertyDefinition) { this.propertyDefinition = propertyDefinition; if (this.propertyDefinition != null){ name = this.propertyDefinition.getName(); fullPropertyDefinitionPath = this.propertyDefinition.getFullPath(); } else{ name = null; fullPropertyDefinitionPath = null; } } private String localizedFullPath; protected void throwExceptionIfPropertyIsMultiple() { if (isMultiple()) throw new MultipleOccurenceException(getFullPath()); } protected void throwExceptionIfPropertyIsSingleValue() { if (!isMultiple()) throw new SingleOccurenceException(getFullPath()); } protected boolean isMultiple() { return (propertyDefinition == null)? false: propertyDefinition.isMultiple(); } protected boolean isSingle() { return ! isMultiple(); } public String getName() { return name; } public P getParentProperty() { return parentProperty; } public void setParent(P parent) { this.parentProperty = parent; resetPaths(); } /** * Return full path for this property including any index numbers * @return */ public String getFullPath() { if (StringUtils.isNotBlank(fullPath)) return fullPath; if (parentProperty==null) fullPath = name; else { int indexForCmsProperty = 0; //Only ComplexCmsProperties can have index if (this instanceof CmsPropertyIndexable) indexForCmsProperty = ((CmsPropertyIndexable)this).getIndex(); String parentFullPath = parentProperty.getFullPath(); fullPath = PropertyPath.createFullPropertyPath(parentFullPath, name); if (indexForCmsProperty > 0 ) { fullPath += CmsConstants.LEFT_BRACKET + indexForCmsProperty + CmsConstants.RIGHT_BRACKET; } } return fullPath; } public String getPath(){ if (StringUtils.isNotBlank(path)) return path; path = PropertyPath.getPathAfterFirstLevel(getFullPath()); return path; } public String getLocalizedLabelOfFullPathforLocaleWithDelimiter(String locale, String delimiter) { if (StringUtils.isNotBlank(localizedFullPath)) return localizedFullPath; localizedFullPath = getLocalizedLabelForLocale(locale); if (StringUtils.isBlank(localizedFullPath)) localizedFullPath = name; if (parentProperty != null){ String parentLocalizedFullPath = parentProperty.getLocalizedLabelOfFullPathforLocaleWithDelimiter(locale, delimiter); int indexForCmsProperty = 0; //Only ComplexCmsProperties can have index if (this instanceof CmsPropertyIndexable) indexForCmsProperty = ((CmsPropertyIndexable)this).getIndex(); localizedFullPath = PropertyPath.createFullPropertyPathWithDelimiter(parentLocalizedFullPath, localizedFullPath, delimiter); if (indexForCmsProperty > 0 || (indexForCmsProperty == 0 && ValueType.Complex == getValueType() && isMultiple())) localizedFullPath += CmsConstants.LEFT_BRACKET + indexForCmsProperty + CmsConstants.RIGHT_BRACKET; } return localizedFullPath; } public String getLocalizedLabelOfFullPathforLocale(String locale) { return getLocalizedLabelOfFullPathforLocaleWithDelimiter(locale, CmsConstants.PERIOD_DELIM); } public String toString() { return getFullPath(); } @Override /** * Since localized labels are defined in definition's level, * {@link LocalizableEntity#getLocalizedLabelForLocale(String locale)} must * be overridden. */ public String getLocalizedLabelForLocale(String locale) { return getPropertyDefinition().getDisplayName().getLocalizedLabelForLocale(locale); } /** * Since localized labels are defined in definition's level, * {@link Localization#getAvailableLocalizedLabel(String)} must * be implemented to use the localization from definition and not the localization inside the property which is always null. */ @Override public String getAvailableLocalizedLabel(String preferredLocale) { return getPropertyDefinition().getDisplayName().getAvailableLocalizedLabel(preferredLocale); } @Override /** * Since localized labels are defined in definition's level, * {@link LocalizableEntity#getLocalizedLabels()} must * be overridden. */ public Map<String, String> getLocalizedLabels() { return getPropertyDefinition().getDisplayName().getLocalizedLabels(); } @Override /** * Since localized labels are defined in definition's level, * {@link LocalizableEntity#addLocalizedLabel(String locale, String localizedName)} must * be overridden. */ public void addLocalizedLabel(String locale, String localizedName) { throw new CmsException("Localized labels cannot be defined through property level"); } public void resetPaths() { fullPath = null; path=null; permanentPath = null; fullPermanentPath = null; } //Useful method to obtain the id of content object //which contains this property public String getContentObjectId(){ if (parentProperty != null && parentProperty instanceof CmsPropertyImpl){ return ((CmsPropertyImpl)parentProperty).getContentObjectId(); } return null; } //Useful method to obtain the system name of content object //which contains this property public String getContentObjectSystemName(){ if (parentProperty != null && parentProperty instanceof CmsPropertyImpl){ return ((CmsPropertyImpl)parentProperty).getContentObjectSystemName(); } return null; } /** * */ public void clean() { setId(null); permanentPath = null; fullPermanentPath = null; } @Override public String getFullPermanentPath() { if (StringUtils.isNotBlank(fullPermanentPath)) return fullPermanentPath; if (parentProperty==null){ fullPermanentPath = name; } else{ String propertyId = null; if (this instanceof ComplexCmsProperty && getPropertyDefinition().isMultiple()){ // use Identifier only if property is a complex property and can have multiple values propertyId = ((ComplexCmsProperty)this).getId(); if (propertyId == null || propertyId.trim().isEmpty()){ throw new CmsException("Unable to generate permanent path for property "+getFullPath()+" because it has not yet been saved"); } } String parentFullPermanentPath = parentProperty.getFullPermanentPath(); fullPermanentPath = PropertyPath.createFullPropertyPath(parentFullPermanentPath, name); if (propertyId != null){ fullPermanentPath += CmsConstants.LEFT_BRACKET + propertyId + CmsConstants.RIGHT_BRACKET; } } return fullPermanentPath; } @Override public String getPermanentPath() { if (StringUtils.isNotBlank(permanentPath)) return permanentPath; permanentPath = PropertyPath.getPathAfterFirstLevel(getFullPermanentPath()); return permanentPath; } }