/* * 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.definition; import java.io.Serializable; import java.net.URI; import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; import javax.xml.namespace.QName; import org.apache.commons.lang.StringUtils; import org.betaconceptframework.astroboa.api.model.definition.CmsDefinition; 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.visitor.DefinitionVisitor; import org.betaconceptframework.astroboa.api.model.visitor.DefinitionVisitor.VisitType; /** * Abstract Implementation class for ComplexPropertyDefinition. * * @author Gregory Chomatas (gchomatas@betaconcept.com) * @author Savvas Triantafyllou (striantafyllou@betaconcept.com) * */ abstract class AbstractComplexCmsPropertyDefinitionImpl extends CmsPropertyDefinitionImpl implements ComplexCmsPropertyDefinition, Serializable{ /** * */ private static final long serialVersionUID = 2161756866624747367L; private final ComplexPropertyDefinitionHelper complexPropertyDefinitionHelper; //Flag indicating whether parent's child definitions have been loaded //in case this definition is the same with its parent private boolean parentChildDefinitionsHaveBeenLoaded; //This is the uri of file containing the schema for this definition private URI definitionFileURI; //This is the name of the type of Complex property protected String typeName; //Flag indicating that this definition is the same with one of its grand parent //and when asked its grand parent child property definitions will be cloned //here protected QName qNameOfParentDefinitionWithTheSameType; public AbstractComplexCmsPropertyDefinitionImpl(QName qualifiedName, Localization description, Localization displayName, boolean obsolete, boolean multiple, boolean mandatory, String restrictReadToRoles, String restrictWriteToRoles, Integer order, CmsDefinition parentDefinition, ComplexPropertyDefinitionHelper complexPropertyDefinitionHelper, URI definitionFileURI, QName qNameOfParentDefinitionWithTheSameType, String typeName ) { super(qualifiedName, description, displayName, obsolete, multiple, mandatory, order, restrictReadToRoles, restrictWriteToRoles, parentDefinition); this.complexPropertyDefinitionHelper = complexPropertyDefinitionHelper; this.qNameOfParentDefinitionWithTheSameType = qNameOfParentDefinitionWithTheSameType; if (qNameOfParentDefinitionWithTheSameType == null){ parentChildDefinitionsHaveBeenLoaded = true; } this.definitionFileURI = definitionFileURI; this.typeName = typeName; } protected void cloneParentsChildDefinitions(){ if (definitionIsRecursiveAndItsChildDefinitionHaveNotBeenLoaded()){ ComplexCmsPropertyDefinition ancestorDefinitionWithTheSameType = locateParentDefinintionWithSameType(); if (ancestorDefinitionWithTheSameType != null){ Collection<CmsPropertyDefinition> childPropertiesOfParentDefinition = ancestorDefinitionWithTheSameType.getChildCmsPropertyDefinitions().values(); Map<String, CmsPropertyDefinition> childPropertyDefinitions = new LinkedHashMap<String, CmsPropertyDefinition>(); for (CmsPropertyDefinition childPropertyDefinitionOfParentDefinition : childPropertiesOfParentDefinition){ childPropertyDefinitions.put(childPropertyDefinitionOfParentDefinition.getName(), ((CmsPropertyDefinitionImpl)childPropertyDefinitionOfParentDefinition).clone((this))); } complexPropertyDefinitionHelper.setChildPropertyDefinitions(childPropertyDefinitions); parentChildDefinitionsHaveBeenLoaded = true; resetDepth(); } } } public ComplexCmsPropertyDefinition locateParentDefinintionWithSameType() { CmsDefinition ancestorDefinition = getParentDefinition(); while (ancestorDefinition != null && ancestorDefinition instanceof ComplexCmsPropertyDefinition){ if ( StringUtils.equals(((ComplexCmsPropertyDefinitionImpl)ancestorDefinition).getTypeName(), typeName)){ return (ComplexCmsPropertyDefinition) ancestorDefinition; } ancestorDefinition = ((ComplexCmsPropertyDefinition)ancestorDefinition).getParentDefinition(); } return null; } protected boolean definitionIsRecursiveAndItsChildDefinitionHaveNotBeenLoaded() { return qNameOfParentDefinitionWithTheSameType != null && ! parentChildDefinitionsHaveBeenLoaded; } public CmsPropertyDefinition getChildCmsPropertyDefinition( String childCmsPropertyPath) { return complexPropertyDefinitionHelper.getChildCmsPropertyDefinition(childCmsPropertyPath); } public Map<String, CmsPropertyDefinition> getChildCmsPropertyDefinitions() { return complexPropertyDefinitionHelper.getChildPropertyDefinitions(); } public Map<String, CmsPropertyDefinition> getSortedChildCmsPropertyDefinitionsByAscendingOrderAndLocale( String locale) { return complexPropertyDefinitionHelper.getSortedChildCmsPropertyDefinitionsByAscendingOrderAndLocale(locale); } public Map<String, CmsPropertyDefinition> getSortedChildCmsPropertyDefinitionsByAscendingOrderAndValueTypeAndLocale( String locale) { return complexPropertyDefinitionHelper.getSortedChildCmsPropertyDefinitionsByAscendingOrderAndValueTypeAndLocale(locale); } public boolean hasChildCmsPropertyDefinition(String childCmsPropertyPath) { return complexPropertyDefinitionHelper.hasChildCmsPropertyDefinition(childCmsPropertyPath); } public boolean hasChildCmsPropertyDefinitions() { return complexPropertyDefinitionHelper.hasPropertyDefinitions(); } public void accept(DefinitionVisitor visitor) { if (visitor == null) return; //Visit Complex Property visitor.visitComplexPropertyDefinition(this); //Now continue to its children switch (visitor.getVisitType()) { case Children: //Do not visit grand children visitor.setVisitType(VisitType.Self); //Visit children visitSubPropertyDefinitions(visitor); //Restore previous state of visitor visitor.setVisitType(VisitType.Children); break; case Full: visitSubPropertyDefinitions(visitor); default: //Do nothing; break; } } private void visitSubPropertyDefinitions(DefinitionVisitor visitor) { visitor.startChildDefinitionsVisit(this); //Now send visitor to visit sub properties if (hasChildCmsPropertyDefinitions()){ //Visit children definitions Map<String, CmsPropertyDefinition> childCmsPropertyDefinitions = getChildCmsPropertyDefinitions(); for (CmsPropertyDefinition propertyDefinition: childCmsPropertyDefinitions.values()){ //Visit child propertyDefinition.accept(visitor); } } visitor.finishedChildDefinitionsVisit(this); } public URI getDefinitionFileURI() { return definitionFileURI; } public String getTypeName() { return typeName; } public boolean isRecursive(){ return qNameOfParentDefinitionWithTheSameType != null; } public void checkIfRecursiveAndCloneParentChildDefinitions() { if (isRecursive()){ cloneParentsChildDefinitions(); } } public int getDepth(){ if (complexPropertyDefinitionHelper == null){ return 0; } return complexPropertyDefinitionHelper.getDepth(); } public void resetDepth() { if (complexPropertyDefinitionHelper!=null){ complexPropertyDefinitionHelper.resetDepth(); } if (getParentDefinition() instanceof ContentObjectTypeDefinitionImpl){ ((ContentObjectTypeDefinitionImpl)getParentDefinition()).resetDepth(); } else if (getParentDefinition() instanceof ComplexCmsPropertyDefinitionImpl){ ((ComplexCmsPropertyDefinitionImpl)getParentDefinition()).resetDepth(); } } }