package com.temenos.interaction.sdk.interaction; /* * #%L * interaction-sdk * %% * Copyright (C) 2012 - 2013 Temenos Holdings N.V. * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% */ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.ws.rs.HttpMethod; import org.odata4j.edm.EdmDataServices; import org.odata4j.edm.EdmEntitySet; import org.odata4j.edm.EdmEntityType; import org.odata4j.edm.EdmSimpleType; import org.odata4j.edm.EdmType; import com.temenos.interaction.core.entity.EntityMetadata; import com.temenos.interaction.core.entity.Metadata; import com.temenos.interaction.core.entity.vocabulary.terms.TermValueType; import com.temenos.interaction.sdk.interaction.state.IMState; /** * This class holds information about the interaction model */ public class InteractionModel { private String domain; private String name; private String basepath; private IMState exceptionState = null; private Map<String, IMState> errorHandlerStates = new HashMap<String, IMState>(); //state name, state private Map<String, IMResourceStateMachine> entityRsmMap = new HashMap<String, IMResourceStateMachine>(); /** * Construct an empty model */ public InteractionModel() { } /** * Construct an initial model from odata4j metadata * @param edmDataServices odata4j metadata */ public InteractionModel(EdmDataServices edmDataServices) { name = edmDataServices.getSchemas().get(0).getEntityContainers().get(0).getName(); for (EdmEntitySet entitySet : edmDataServices.getEntitySets()) { addResourceStateMachine(createInitialResourceStateMachine(entitySet)); } } /** * Construct an initial model from entity metadata * @param metadata metadata */ public InteractionModel(Metadata metadata) { name = metadata.getModelName(); for (EntityMetadata entityMetadata : metadata.getEntitiesMetadata().values()) { addResourceStateMachine(createInitialResourceStateMachine(entityMetadata)); } } /** * Create an initial RSM with a collection and entity state * @param entitySet Entity metadata * @return resource state machine */ public IMResourceStateMachine createInitialResourceStateMachine(EdmEntitySet entitySet) { EdmEntityType entityType = entitySet.getType(); String entityName = entityType.getName(); String collectionStateName = entitySet.getName(); String entityStateName = entityName.toLowerCase(); String mappedEntityProperty = entityType.getKeys().size() > 0 ? entityType.getKeys().get(0) : "id"; String pathParametersTemplate = getUriTemplateParameters(entityType); return new IMResourceStateMachine(entityName, collectionStateName, entityStateName, mappedEntityProperty, pathParametersTemplate); } /** * Create an initial RSM with a collection and entity state * @param entityMetadata Entity metadata * @return resource state machine */ public IMResourceStateMachine createInitialResourceStateMachine(EntityMetadata entityMetadata) { return createInitialResourceStateMachine(entityMetadata, HttpMethod.GET); } /** * Create an initial RSM with a collection and entity state * @param entityMetadata Entity metadata * @param methodGetEntity Method for GET entity * @return resource state machine */ public IMResourceStateMachine createInitialResourceStateMachine(EntityMetadata entityMetadata, String methodGetEntity) { return createInitialResourceStateMachine(entityMetadata, methodGetEntity, null); } /** * Create an initial RSM with a collection and entity state * @param entityMetadata Entity metadata * @param methodGetEntity Method for GET entity * @return resource state machine */ public IMResourceStateMachine createInitialResourceStateMachine(EntityMetadata entityMetadata, String methodGetEntity, String collectionRels) { String entityName = entityMetadata.getEntityName(); String collectionStateName = entityName + "s"; String entityStateName = entityName.toLowerCase(); List<String> idFields = entityMetadata.getIdFields(); String mappedEntityProperty = idFields.size() > 0 ? idFields.get(0) : "id"; String pathParametersTemplate = getUriTemplateParameters(entityMetadata); return new IMResourceStateMachine(entityName, collectionStateName, entityStateName, methodGetEntity, mappedEntityProperty, pathParametersTemplate, collectionRels); } public String getUriTemplateParameters(EntityMetadata entityMetadata) { String paramTemplate = ""; List<String> keys = entityMetadata.getIdFields(); for(String key : keys) { if(!paramTemplate.equals("")) { paramTemplate += ","; } String keyPropertyType = entityMetadata.getTermValue(key, TermValueType.TERM_NAME); if(keyPropertyType != null && isQuotedUriTemplateParameter(keyPropertyType)) { paramTemplate += "'{" + (keys.size() > 1 ? key : "id") + "}'"; //These types should be enclosed in single quotes } else { paramTemplate += "{" + (keys.size() > 1 ? key : "id") + "}"; } } return paramTemplate; } private boolean isQuotedUriTemplateParameter(String entityType) { return entityType.equals(TermValueType.IMAGE) || entityType.equals(TermValueType.TIMESTAMP) || entityType.equals(TermValueType.DATE) || entityType.equals(TermValueType.TEXT) || entityType.equals(TermValueType.ENCRYPTED_TEXT); } public String getUriTemplateParameters(EdmEntityType entityType) { String paramTemplate = ""; List<String> keys = entityType.getKeys(); for(String key : keys) { if(!paramTemplate.equals("")) { paramTemplate += ","; } EdmType keyPropertyType = entityType.findDeclaredProperty(key).getType(); if(keyPropertyType != null && isQuotedUriTemplateParameter(keyPropertyType)) { paramTemplate += "'{" + (keys.size() > 1 ? key : "id") + "}'"; //These types should be enclosed in single quotes } else { paramTemplate += "{" + (keys.size() > 1 ? key : "id") + "}"; } } return paramTemplate; } private boolean isQuotedUriTemplateParameter(EdmType type) { return type.equals(EdmSimpleType.DATETIME) || type.equals(EdmSimpleType.STRING); } public void addResourceStateMachine(IMResourceStateMachine resourceStateMachine) { entityRsmMap.put(resourceStateMachine.getEntityName(), resourceStateMachine); } public List<IMResourceStateMachine> getResourceStateMachines() { return new ArrayList<IMResourceStateMachine>(entityRsmMap.values()); } public IMResourceStateMachine findResourceStateMachine(String entityName) { return entityRsmMap.get(entityName); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDomain() { return domain; } public void setDomain(String domain) { this.domain = domain; } public String getBasepath() { return basepath; } public void setBasepath(String basepath) { this.basepath = basepath; } public void setExceptionState(IMState exceptionState) { this.exceptionState = exceptionState; } public IMState getExceptionState() { return exceptionState; } public boolean hasExceptionState() { return exceptionState != null; } public Collection<IMState> getErrorHandlerStates() { return errorHandlerStates.values(); } public void addErrorHandlerState(IMState errorHandlerState) { errorHandlerStates.put(errorHandlerState.getName(), errorHandlerState); } public IMState getErrorHandlerState(String stateName) { return errorHandlerStates.get(stateName); } }