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.util; import org.apache.commons.lang.StringUtils; import org.betaconceptframework.astroboa.api.model.*; import org.betaconceptframework.astroboa.api.model.definition.CmsPropertyDefinition; import org.betaconceptframework.astroboa.api.model.exception.CmsException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.List; /** * Class responsible to return a property of an object using the * path provided. * * The path may contain identifiers instead of indices to indicate which of the property to use. * * All the parts of the path represent a complex property except from the last part which * represents a simple property. In this part, if the property is a multiple value property, * users have to use indices to specify which value of the * property to return . In the case of a binary property they may use the identifier of the * binary channel as well. * * The path follows the pattern {@link CmsConstants#PROPERTY_PATH_WITH_ID_REG_EXP_FOR_RESTEASY} * * @author Gregory Chomatas (gchomatas@betaconcept.com) * @author Savvas Triantafyllou (striantafyllou@betaconcept.com) * */ public class PropertyExtractor { private static final Logger logger = LoggerFactory.getLogger(PropertyExtractor.class); private String identifierOfTheValueOfTheProperty = null; private int indexOfTheValueOfTheProperty = 0; private CmsProperty<?, ?> property = null; public PropertyExtractor(ContentObject contentObject, String propertyPath) throws Exception { if (StringUtils.isNotBlank(propertyPath) && contentObject != null) { property = contentObject.getComplexCmsRootProperty(); String[] pathParts = StringUtils.split(propertyPath, CmsConstants.PERIOD_DELIM); int count = 0; for (String pathPart : pathParts) { boolean lastPart = ++count == pathParts.length; String parentPropertyPermanentPath = property.getFullPath(); String childPropertyName = StringUtils.substringBeforeLast(pathPart, CmsConstants.LEFT_BRACKET); if (lastPart) { String identifierOrIndexOfTheValue = retrieveIdentifierOrIndexFromPath(pathPart); property = ((ComplexCmsProperty) property).getChildProperty(childPropertyName); if (property == null) { throw new CmsException("Cannot retrieve property " + pathPart + " from parent property " + parentPropertyPermanentPath); } if (identifierOrIndexOfTheValue != null) { if (CmsConstants.UUIDPattern.matcher(identifierOrIndexOfTheValue).matches()) { identifierOfTheValueOfTheProperty = identifierOrIndexOfTheValue; } else { indexOfTheValueOfTheProperty = Integer.parseInt(identifierOrIndexOfTheValue); } } } else { //We are in the middle of the path. String identifierOfTheChildProperty = retrieveIdentifierOrIndexFromPath(pathPart); boolean childPropertyIsDefined = ((ComplexCmsProperty) property) .isChildPropertyDefined(childPropertyName); if (!childPropertyIsDefined) { throw new Exception("Could not locate definition for property " + childPropertyName); } //Retrieve definition CmsPropertyDefinition childPropertyDefinition = ((ComplexCmsProperty) property) .getPropertyDefinition().getChildCmsPropertyDefinition(childPropertyName); if (childPropertyDefinition == null) { //Property has been defined. Since no definition is found check if this property is an aspect if (property instanceof ComplexCmsRootProperty && ((ComplexCmsRootProperty) property).hasAspect(childPropertyName)) { childPropertyDefinition = ((ComplexCmsRootProperty) property).getAspectDefinitions() .get(childPropertyName); } } if (childPropertyDefinition == null) { throw new Exception("Could not locate definition for property " + childPropertyName); } if (childPropertyDefinition.getValueType() == ValueType.Complex) { //Child property is a multiple value property //Iterate through the returned properties to //match the property with the provided identifier if any if (childPropertyDefinition.isMultiple()) { property = retrieveChildComplexCmsPropertyFromAListOfProperties( identifierOfTheChildProperty, childPropertyName); } else { //Child property is a single value property CmsProperty<?, ?> childProperty = ((ComplexCmsProperty) property) .getChildProperty(childPropertyName); if (identifierOfTheChildProperty != null) { //User has an identifier. Check that this is valid if (StringUtils.equals(identifierOfTheChildProperty, childProperty.getId())) { property = childProperty; } else { throw new Exception("Property " + childPropertyName + " has been retrieved from parent property " + parentPropertyPermanentPath + " but its identifier " + childProperty.getId() + " does not match with the one provided " + identifierOfTheChildProperty); } } else { property = childProperty; } } } else { throw new CmsException("Property " + pathPart + " does not correspond to a complex property of the property " + parentPropertyPermanentPath); } } } } } private CmsProperty<?, ?> retrieveChildComplexCmsPropertyFromAListOfProperties(String identifierOfChildProperty, String childPropertyName) throws Exception { List<CmsProperty<?, ?>> childProperties = ((ComplexCmsProperty) property) .getChildPropertyList(childPropertyName); logger.info("Checking if child property {}[{}] is in property list", childPropertyName, identifierOfChildProperty, childProperties); if (childProperties == null || childProperties.isEmpty()) { throw new Exception("Empty property list returned"); } //No identifier is provided. Return the first from the list if (identifierOfChildProperty == null) { return childProperties.get(0); } else { Integer childPropertyIndex = getIndex(identifierOfChildProperty); if (childPropertyIndex == -1) { // it is an identifier for (CmsProperty childProperty : childProperties) { if (StringUtils.equals(identifierOfChildProperty, childProperty.getId())) { return childProperty; } } } else { return childProperties.get(childPropertyIndex); } } throw new Exception("Could not locate child property " + childPropertyName + " with identifier " + identifierOfChildProperty + " in parent property " + property.getFullPath()); } private String retrieveIdentifierOrIndexFromPath(String pathPart) { if (StringUtils.isBlank(pathPart)) { return null; } return StringUtils.substringBetween(pathPart, CmsConstants.LEFT_BRACKET, CmsConstants.RIGHT_BRACKET); } public String getIdentifierOfTheValueOfTheProperty() { return identifierOfTheValueOfTheProperty; } public int getIndexOfTheValueOfTheProperty() { return indexOfTheValueOfTheProperty; } public CmsProperty<?, ?> getProperty() { return property; } private Integer getIndex(String identifierOrIndex) { try { return Integer.parseInt(identifierOrIndex); } catch (NumberFormatException e) { return -1; } } }