Java tutorial
/* * 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.IOException; import java.io.ObjectInputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang.StringUtils; import org.betaconceptframework.astroboa.api.model.ComplexCmsProperty; import org.betaconceptframework.astroboa.api.model.ComplexCmsRootProperty; import org.betaconceptframework.astroboa.api.model.definition.CmsPropertyDefinition; import org.betaconceptframework.astroboa.api.model.definition.ComplexCmsPropertyDefinition; import org.betaconceptframework.astroboa.api.model.definition.ContentObjectTypeDefinition; import org.betaconceptframework.astroboa.api.model.exception.CmsException; import org.betaconceptframework.astroboa.api.model.io.ResourceRepresentationType; import org.betaconceptframework.astroboa.model.impl.definition.ComplexCmsPropertyDefinitionImpl; import org.betaconceptframework.astroboa.model.impl.definition.ContentObjectTypeDefinitionImpl; import org.betaconceptframework.astroboa.model.impl.definition.LocalizableCmsDefinitionImpl; import org.betaconceptframework.astroboa.model.lazy.LazyLoader; import org.betaconceptframework.astroboa.util.PropertyPath; import org.slf4j.LoggerFactory; /** * @author Gregory Chomatas (gchomatas@betaconcept.com) * @author Savvas Triantafyllou (striantafyllou@betaconcept.com) * */ public class ComplexCmsRootPropertyImpl extends ComplexCmsPropertyImpl<ComplexCmsPropertyDefinition, ComplexCmsProperty<? extends ComplexCmsPropertyDefinition, ? extends ComplexCmsProperty<?, ?>>> implements ComplexCmsRootProperty, AspectDefinitionManager, Serializable { /** * */ private static final long serialVersionUID = -6855093200508354921L; private List<String> aspects = new ArrayList<String>(); private transient Map<String, ComplexCmsPropertyDefinition> aspectDefinitions = new HashMap<String, ComplexCmsPropertyDefinition>(); private String contentObjectSystemName; public void loadAspectDefinition(String aspect) throws Exception { //Check that aspect has not been defined in content type definition if (getPropertyDefinition() == null) throw new CmsException("ComplexCmsRootProperty is not attached to any definition"); //NOTE :In case content object type definition contains a property which refers to this aspect //but property's name is different than aspect's one, the check will pass through //and aspect will be added to content object if (!getPropertyDefinition().hasChildCmsPropertyDefinition(aspect)) { //Get Aspect definition ComplexCmsPropertyDefinition aspectDefinition = null; LazyLoader lazyLoader = getLazyLoader(); if (lazyLoader != null) { lazyLoader.activateClientContextForAuthenticationToken(authenticationToken); aspectDefinition = (ComplexCmsPropertyDefinition) lazyLoader.getDefinitionService() .getCmsDefinition(aspect, ResourceRepresentationType.DEFINITION_INSTANCE, false); } if (aspectDefinition == null) { LoggerFactory.getLogger(getClass()).warn("Definition for aspect " + aspect + " was not found"); } else { //Attach aspect definition to Content Object aspectDefinitions.put(aspectDefinition.getName(), aspectDefinition); if (!aspects.contains(aspectDefinition.getName())) { aspects.add(aspectDefinition.getName()); } } } } public List<String> getAspects() { return Collections.unmodifiableList(aspects); } public boolean hasAspect(String aspect) { return aspects.contains(aspect); } @Override public boolean removeChildProperty(String propertyPath) { final boolean propertyWasRemoved = super.removeChildProperty(propertyPath); //Check if property is an aspect PropertyPath path = new PropertyPath(propertyPath); if (path.getPropertyDescendantPath() == null && path.getPropertyIndex() == PropertyPath.NO_INDEX) { String propertyName = path.getPropertyName(); if (aspects.contains(propertyName)) { //Remove aspect only if property is not there if (cmsPropertyHasBeenLoadedAndRemoved(propertyName) || !isChildPropertyLoaded(propertyName)) { if (aspectDefinitions.containsKey(propertyName)) { aspectDefinitions.remove(propertyName); } aspects.remove(propertyName); } } } return propertyWasRemoved; } @Override protected CmsPropertyDefinition getChildPropertyDefinition(String childPropertyName) { if (getPropertyDefinition() != null) { CmsPropertyDefinition childCmsPropertyDefinition = getPropertyDefinition() .getChildCmsPropertyDefinition(childPropertyName); if (childCmsPropertyDefinition == null) { PropertyPath childPropertyPath = new PropertyPath(childPropertyName); String firstChildInPathPropertyName = childPropertyPath.getPropertyName(); String restChildPropertyPath = childPropertyPath.getPropertyDescendantPath(); //Try Aspects if (MapUtils.isNotEmpty(aspectDefinitions) && firstChildInPathPropertyName != null) { ComplexCmsPropertyDefinition firstChildCmsPropertyDefinition = aspectDefinitions .get(firstChildInPathPropertyName); if (firstChildCmsPropertyDefinition != null && restChildPropertyPath != null) { //Multi path child property. childCmsPropertyDefinition = firstChildCmsPropertyDefinition .getChildCmsPropertyDefinition(restChildPropertyPath); } else { childCmsPropertyDefinition = firstChildCmsPropertyDefinition; } } if (childCmsPropertyDefinition == null && firstChildInPathPropertyName != null) { //Try to load it as an aspect try { loadAspectDefinition(firstChildInPathPropertyName); //Re check aspects if (MapUtils.isNotEmpty(aspectDefinitions)) { ComplexCmsPropertyDefinition firstChildCmsPropertyDefinition = aspectDefinitions .get(firstChildInPathPropertyName); if (firstChildCmsPropertyDefinition != null && restChildPropertyPath != null) { //Multi path child property. childCmsPropertyDefinition = firstChildCmsPropertyDefinition .getChildCmsPropertyDefinition(restChildPropertyPath); } else { childCmsPropertyDefinition = firstChildCmsPropertyDefinition; } if (childCmsPropertyDefinition == null && aspectDefinitions.containsKey(firstChildInPathPropertyName)) { //Definition was not found. Remove aspect since it is not needed any more aspectDefinitions.remove(firstChildInPathPropertyName); } } } catch (Exception e) { //Property is not an aspect LoggerFactory.getLogger(getClass()).warn("No definition found for property " + childPropertyName + " in content object " + getContentObjectId(), e); } if (childCmsPropertyDefinition == null) { LoggerFactory.getLogger(getClass()).warn( "Found no definition for child property '{}' in property {} in content object {}", new Object[] { childPropertyName, this.getFullPath(), getContentObjectId() }); } } } return childCmsPropertyDefinition; } throw new CmsException("Property " + getFullPath() + " is not complex."); } @Override public boolean isChildPropertyDefined(String propertyPath) { boolean isPropertyDefined = false; isPropertyDefined = super.isChildPropertyDefined(propertyPath); if (!isPropertyDefined && MapUtils.isNotEmpty(aspectDefinitions)) { PropertyPath aspectPath = new PropertyPath(propertyPath); String aspectName = aspectPath.getPropertyName(); //Check if there are any aspect definitions if (aspectDefinitions.containsKey(aspectName)) { //Aspect exists. Check to see if we need to go any further String aspectDescendantPath = aspectPath.getPropertyDescendantPath(); if (StringUtils.isNotBlank(aspectDescendantPath)) { //Check aspect's children definitions return (aspectDefinitions.get(aspectName).hasChildCmsPropertyDefinition(aspectDescendantPath)); } //No aspect children in aspect path. Definition for aspect was requested ad it was found return true; } } return isPropertyDefined; } @Override public Map<String, ComplexCmsPropertyDefinition> getAspectDefinitions() { return Collections.unmodifiableMap(aspectDefinitions); } //Override deserialization process to inject //and lazyLoader private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { //Deserialize bean normally ois.defaultReadObject(); //Inject lazyLoader LazyLoader lazyLoader = getLazyLoader(); if (lazyLoader != null) { lazyLoader.activateClientContextForAuthenticationToken(authenticationToken); //In this case fullPropertyDefinitionPath is the name of content type ContentObjectTypeDefinition contentTypeDefinition = (ContentObjectTypeDefinition) lazyLoader .getDefinitionService().getCmsDefinition(fullPropertyDefinitionPath, ResourceRepresentationType.DEFINITION_INSTANCE, false); if (contentTypeDefinition != null) { setPropertyDefinition(new ComplexCmsPropertyDefinitionImpl(contentTypeDefinition.getQualifiedName(), ((LocalizableCmsDefinitionImpl) contentTypeDefinition).cloneDescription(), ((LocalizableCmsDefinitionImpl) contentTypeDefinition).cloneDisplayName(), false, false, true, null, null, null, null, ((ContentObjectTypeDefinitionImpl) contentTypeDefinition) .getComplexPropertyDefinitionHelper(), ((ContentObjectTypeDefinitionImpl) contentTypeDefinition).getDefinitionFileURI(), contentTypeDefinition.getPropertyPathsWhoseValuesCanBeUsedAsALabel(), true, null, contentTypeDefinition.getName(), true)); } //Load all aspects aspectDefinitions = new HashMap<String, ComplexCmsPropertyDefinition>(); if (aspects != null) { for (String aspect : aspects) { try { loadAspectDefinition(aspect); } catch (Exception e) { throw new IOException(e); } } } } } @Override public String getContentObjectId() { return getId(); } @Override public String getContentObjectSystemName() { return contentObjectSystemName; } public void setContentObjectSystemName(String contentObjectSystemName) { this.contentObjectSystemName = contentObjectSystemName; } }