/* * 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 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Astroboa. If not, see <http://www.gnu.org/licenses/>. */ package org.betaconceptframework.astroboa.util; import java.io.File; import java.net.URI; import org.apache.commons.lang.StringUtils; import org.betaconceptframework.astroboa.api.model.BinaryChannel; import org.betaconceptframework.astroboa.api.model.BinaryChannel.ContentDispositionType; import org.betaconceptframework.astroboa.api.model.BinaryProperty; import org.betaconceptframework.astroboa.api.model.CmsProperty; import org.betaconceptframework.astroboa.api.model.CmsRepository; import org.betaconceptframework.astroboa.api.model.ContentObject; import org.betaconceptframework.astroboa.api.model.Space; import org.betaconceptframework.astroboa.api.model.Taxonomy; import org.betaconceptframework.astroboa.api.model.Topic; 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.ContentObjectTypeDefinition; import org.betaconceptframework.astroboa.api.model.definition.SimpleCmsPropertyDefinition; import org.betaconceptframework.astroboa.api.model.io.ResourceRepresentationType; import org.betaconceptframework.astroboa.context.AstroboaClientContextHolder; import org.betaconceptframework.astroboa.model.impl.CmsPropertyImpl; import org.betaconceptframework.astroboa.model.impl.definition.ComplexCmsPropertyDefinitionImpl; import org.betaconceptframework.astroboa.model.impl.definition.ContentObjectTypeDefinitionImpl; import org.betaconceptframework.astroboa.model.impl.item.CmsBuiltInItem; /** * @author Gregory Chomatas (gchomatas@betaconcept.com) * @author Savvas Triantafyllou (striantafyllou@betaconcept.com) * */ public class ResourceApiURLUtils { public static String generateUrlForType(Class<?> type, UrlProperties urlProperties) { if (urlProperties == null){ urlProperties = new UrlProperties(); } StringBuilder sb = new StringBuilder(); if (!urlProperties.isRelative()){ addHost(sb); } addResourceApiPrefix(sb); addRepositoryId(sb); addURLPartForType(sb, type, urlProperties); addOutput(urlProperties.getResourceRepresentationType(), sb, type); return sb.toString(); } public static String generateUrlForEntity(Object cmsEntity, UrlProperties urlProperties) { if (urlProperties == null){ urlProperties = new UrlProperties(); } if (cmsEntity instanceof BinaryChannel){ return ((BinaryChannel)cmsEntity).buildResourceApiURL(null, null, null, null, null, urlProperties.isFriendly(), urlProperties.isRelative()); } StringBuilder sb = new StringBuilder(); if (!urlProperties.isRelative()){ addHost(sb); } addResourceApiPrefix(sb); addRepositoryId(sb); addURLForEntity(sb, cmsEntity, urlProperties); //Do not add resource representation output if property is a Binary Property //since its url practically represents the binary content //TODO: Clarify this issue if (! (cmsEntity instanceof BinaryProperty)){ addOutput(urlProperties.getResourceRepresentationType(), sb, cmsEntity.getClass()); } return sb.toString(); } private static void addURLPartForType(StringBuilder sb, Class<?> type, UrlProperties urlProperties) { if (type == null){ return; } else{ if (ContentObject.class.isAssignableFrom(type) || CmsProperty.class.isAssignableFrom(type) || BinaryChannel.class.isAssignableFrom(type)){ sb.append(CmsConstants.RESOURCE_API_OBJECTS_COLLECTION_URI_PATH); } else if (Topic.class.isAssignableFrom(type)){ sb.append(CmsConstants.RESOURCE_API_TOPICS_COLLECTION_URI_PATH); } else if (Space.class.isAssignableFrom(type)){ sb.append(CmsConstants.FORWARD_SLASH); sb.append(CmsBuiltInItem.Space.getLocalPart()); } else if (Taxonomy.class.isAssignableFrom(type)){ sb.append(CmsConstants.RESOURCE_API_TAXONOMIES_COLLECTION_URI_PATH); } else if (CmsDefinition.class.isAssignableFrom(type)){ sb.append(CmsConstants.RESOURCE_API_MODELS_COLLECTION_URI_PATH); } sb.append(CmsConstants.FORWARD_SLASH); if (urlProperties.isFriendly()){ sb.append(urlProperties.getName()); } else{ sb.append(urlProperties.getIdentifier()); } if (CmsProperty.class.isAssignableFrom(type) || BinaryChannel.class.isAssignableFrom(type)){ sb.append(CmsConstants.FORWARD_SLASH) .append(urlProperties.getPropertyPath()); } } } private static void addURLForEntity(StringBuilder sb, Object cmsEntity, UrlProperties urlProperties) { if (cmsEntity == null){ return ; } if (cmsEntity instanceof Taxonomy){ sb.append(CmsConstants.RESOURCE_API_TAXONOMIES_COLLECTION_URI_PATH) .append(CmsConstants.FORWARD_SLASH); if (urlProperties.isFriendly()){ sb.append(((Taxonomy)cmsEntity).getName()); } else{ sb.append(((Taxonomy)cmsEntity).getId()); } } else if (cmsEntity instanceof Topic){ sb.append(CmsConstants.RESOURCE_API_TOPICS_COLLECTION_URI_PATH) .append(CmsConstants.FORWARD_SLASH); if (urlProperties.isFriendly()){ sb.append(((Topic)cmsEntity).getName()); } else{ sb.append(((Topic)cmsEntity).getId()); } } else if (cmsEntity instanceof Space){ sb.append(CmsConstants.FORWARD_SLASH) .append(CmsBuiltInItem.Space.getLocalPart()) .append(CmsConstants.FORWARD_SLASH); if (urlProperties.isFriendly()){ sb.append(((Space)cmsEntity).getName()); } else{ sb.append(((Space)cmsEntity).getId()); } } else if (cmsEntity instanceof ContentObject){ sb.append(CmsConstants.RESOURCE_API_OBJECTS_COLLECTION_URI_PATH) .append(CmsConstants.FORWARD_SLASH); if (urlProperties.isFriendly()){ sb.append(((ContentObject)cmsEntity).getSystemName()); } else{ sb.append(((ContentObject)cmsEntity).getId()); } } else if (cmsEntity instanceof CmsProperty<?,?>){ sb.append(CmsConstants.RESOURCE_API_OBJECTS_COLLECTION_URI_PATH) .append(CmsConstants.FORWARD_SLASH); if (urlProperties.isFriendly()){ sb.append(((CmsPropertyImpl<?,?>)cmsEntity).getContentObjectSystemName()); } else{ sb.append(((CmsPropertyImpl<?,?>)cmsEntity).getContentObjectId()); } sb.append(CmsConstants.FORWARD_SLASH) .append(((CmsProperty<?,?>)cmsEntity).getPermanentPath()); } else if (cmsEntity instanceof ContentObjectTypeDefinition){ sb.append(CmsConstants.RESOURCE_API_MODELS_COLLECTION_URI_PATH) .append(CmsConstants.FORWARD_SLASH); if (urlProperties.getResourceRepresentationType() !=null && urlProperties.getResourceRepresentationType().equals(ResourceRepresentationType.XSD)){ String schemaFilename = retrieveSchemaFileName((ContentObjectTypeDefinition)cmsEntity); if (schemaFilename != null){ sb.append(schemaFilename); } else{ sb.append(((ContentObjectTypeDefinition)cmsEntity).getName()); } } else{ sb.append(((ContentObjectTypeDefinition)cmsEntity).getName()); } } else if (cmsEntity instanceof CmsPropertyDefinition){ sb.append(CmsConstants.RESOURCE_API_MODELS_COLLECTION_URI_PATH) .append(CmsConstants.FORWARD_SLASH); if (urlProperties.getResourceRepresentationType() !=null && urlProperties.getResourceRepresentationType().equals(ResourceRepresentationType.XSD)){ String schemaFilename = retrieveSchemaFileName((CmsPropertyDefinition)cmsEntity); if (schemaFilename != null){ sb.append(schemaFilename); } else{ sb.append(((CmsPropertyDefinition)cmsEntity).getFullPath()); } } else{ sb.append(((CmsPropertyDefinition)cmsEntity).getFullPath()); } } } private static void addOutput(ResourceRepresentationType<?> resourceRepresentationType, StringBuilder sb, Class<?> type) { //Add output. XML is considered default value and therefore it is not added if (resourceRepresentationType != null && ! resourceRepresentationType.equals(ResourceRepresentationType.XML)){ //Special case. if entity is a definition and output is XSD then do not add this parameter as well // since in this case, the schema filename is provided in the URL if (! CmsDefinition.class.isAssignableFrom(type) || ! resourceRepresentationType.equals(ResourceRepresentationType.XSD)){ sb.append("?output="); sb.append(resourceRepresentationType.getTypeAsString().toLowerCase()); } } } private static void addHost(StringBuilder sb) { CmsRepository activeRepository = AstroboaClientContextHolder.getActiveCmsRepository(); if (activeRepository!= null && StringUtils.isNotBlank(activeRepository.getServerURL())){ sb.append(removeWhitespaceAndTrailingSlash(activeRepository.getServerURL())); } } private static void addResourceApiPrefix(StringBuilder sb) { CmsRepository activeRepository = AstroboaClientContextHolder.getActiveCmsRepository(); if (activeRepository!= null && StringUtils.isNotBlank(activeRepository.getServerURL())){ final String restFulApiBasePath = removeWhitespaceAndTrailingSlash(activeRepository.getRestfulApiBasePath()); if (restFulApiBasePath!=null && ! restFulApiBasePath.startsWith(CmsConstants.FORWARD_SLASH)){ //Append with base URL sb.append(CmsConstants.FORWARD_SLASH); } sb.append(restFulApiBasePath); } } private static void addRepositoryId(StringBuilder sb) { //Add repository identifier sb.append(CmsConstants.FORWARD_SLASH); sb.append(retrieveRepositoryId()); } private static String retrieveRepositoryId() { return AstroboaClientContextHolder.getActiveRepositoryId(); } private static String removeWhitespaceAndTrailingSlash(String urlPath) { if (urlPath == null){ return null; } urlPath = urlPath.trim(); if (urlPath.endsWith("/")) { urlPath = urlPath.substring(0, urlPath.length()-1); } return urlPath; } public static String buildContetApiURLForBinaryProperty(String contentObjectIdOrSystemName, String binaryPropertyPath, String mimeType, Integer width, Integer height, ContentDispositionType contentDispositionType) { StringBuilder contentApiURLBuilder = new StringBuilder(); addHost(contentApiURLBuilder); addResourceApiPrefix(contentApiURLBuilder); addRepositoryId(contentApiURLBuilder); if (StringUtils.isBlank(contentObjectIdOrSystemName) || StringUtils.isBlank(binaryPropertyPath)){ return contentApiURLBuilder.toString(); } // Astroboa RESTful API URL pattern for accessing the value of content object properties // http://server/resource-api/ // <reposiotry-id>/objects/<contentObjectId>/<binaryChannelPropertyValuePath> // ?contentDispositionType=<contentDispositionType>&width=<width>&height=<height> contentApiURLBuilder.append(CmsConstants.RESOURCE_API_OBJECTS_COLLECTION_URI_PATH); contentApiURLBuilder.append(CmsConstants.FORWARD_SLASH+contentObjectIdOrSystemName); contentApiURLBuilder.append(CmsConstants.FORWARD_SLASH+binaryPropertyPath); boolean questionMarkHasBeenUsed = false; if (contentDispositionType !=null){ contentApiURLBuilder .append(CmsConstants.QUESTION_MARK) .append("contentDispositionType") .append(CmsConstants.EQUALS_SIGN) .append(contentDispositionType.toString().toLowerCase()); questionMarkHasBeenUsed = true; } if (StringUtils.isNotBlank(mimeType) && mimeType.startsWith("image/")){ if (width != null && width > 0){ contentApiURLBuilder .append(questionMarkHasBeenUsed ? CmsConstants.AMPERSAND : CmsConstants.QUESTION_MARK) .append("width") .append(CmsConstants.EQUALS_SIGN) .append(width); questionMarkHasBeenUsed = true; } if (height != null && height > 0){ contentApiURLBuilder.append(questionMarkHasBeenUsed ? CmsConstants.AMPERSAND : CmsConstants.QUESTION_MARK) .append("height") .append(CmsConstants.EQUALS_SIGN) .append(height); } } return contentApiURLBuilder.toString(); } public static String retrieveSchemaFileName(CmsDefinition cmsDefinition){ URI cmsDefinitionFileURI = null; if (cmsDefinition instanceof ContentObjectTypeDefinition){ cmsDefinitionFileURI = ((ContentObjectTypeDefinitionImpl)cmsDefinition).getDefinitionFileURI(); } else if (cmsDefinition instanceof ComplexCmsPropertyDefinition){ cmsDefinitionFileURI = ((ComplexCmsPropertyDefinitionImpl)cmsDefinition).getDefinitionFileURI(); } else if (cmsDefinition instanceof SimpleCmsPropertyDefinition){ //It is a simple property. Get its parent to provide with the URI CmsDefinition parentDefinition = ((SimpleCmsPropertyDefinition)cmsDefinition).getParentDefinition(); if (parentDefinition != null && parentDefinition instanceof ComplexCmsPropertyDefinition){ cmsDefinitionFileURI = ((ComplexCmsPropertyDefinitionImpl)parentDefinition).getDefinitionFileURI(); } } if (cmsDefinitionFileURI == null){ return null; } String schemaFilename = StringUtils.substringAfterLast(cmsDefinitionFileURI.toString(), File.separator); if (StringUtils.isBlank(schemaFilename)){ if (!File.separator.equals(CmsConstants.FORWARD_SLASH)){ //try with forward slash. schemaFilename = StringUtils.substringAfterLast(cmsDefinitionFileURI.toString(), CmsConstants.FORWARD_SLASH); } } if (StringUtils.isBlank(schemaFilename)){ return null; } return schemaFilename; } }