package com.temenos.interaction.core.hypermedia; /* * #%L * interaction-core * %% * Copyright (C) 2012 - 2014 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.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.Map; import java.util.Queue; import java.util.Set; import javax.ws.rs.core.Context; import javax.ws.rs.core.UriInfo; public class DefaultResourceStateProvider implements ResourceStateProvider { private ResourceStateMachine hypermediaEngine; PathTree paths = new PathTree(); @Context private UriInfo uriInfo; public DefaultResourceStateProvider(ResourceStateMachine hypermediaEngine) { this.hypermediaEngine = hypermediaEngine; Queue<Transition> queue = new LinkedList<Transition>(); ResourceState initial = hypermediaEngine.getInitial(); paths.put(initial.getPath(), "GET", initial.getName()); Set<Transition> alreadyProcessed = new HashSet<Transition>(); Transition.Builder builder = new Transition.Builder(); alreadyProcessed.add(builder.target(initial).build()); for(Transition transition: initial.getTransitions()) { queue.offer(transition); } while(!queue.isEmpty()) { Transition transition = queue.poll(); if(!alreadyProcessed.contains(transition)) { ResourceState target = transition.getTarget(); String method = transition.getCommand().getMethod(); alreadyProcessed.add(transition); if(target.getPath() != null) { paths.put(target.getPath(), method, target.getName()); for(Transition targetTransition: target.getTransitions()) { if(!alreadyProcessed.contains(targetTransition)) { queue.offer(targetTransition); } } } } } } @Override public boolean isLoaded(String name) { return hypermediaEngine.getResourceStateByName(name) != null; } @Override public ResourceState getResourceState(String name) { return hypermediaEngine.getResourceStateByName(name); } @Override public ResourceState determineState(Event event, String resourcePath) { return hypermediaEngine.determineState(event, resourcePath); } @Override public Map<String, Set<String>> getResourceStatesByPath() { Map<String, Set<String>> results = new HashMap<String, Set<String>>(); Map<String, Set<ResourceState>> statesByPath = hypermediaEngine.getResourceStatesByPath(); for (String key : statesByPath.keySet()) { Set<ResourceState> states = statesByPath.get(key); Set<String> stateNames = new HashSet<String>(); for (ResourceState state : states) { stateNames.add(state.getName()); } results.put(key, stateNames); } return results; } @Override public Map<String, Set<String>> getResourceMethodsByState() { return hypermediaEngine.getInteractionByState(); } @Override public Map<String, String> getResourcePathsByState() { Map<String, String> results = new HashMap<String, String>(); Map<String, ResourceState> statesByName = hypermediaEngine.getResourceStateByName(); for (String key : statesByName.keySet()) { ResourceState resourceState = statesByName.get(key); results.put(key, resourceState.getPath()); } return results; } public void setUriInfo(UriInfo uriInfo) { this.uriInfo = uriInfo; } @Override public ResourceState getResourceState(String httpMethod, String url) throws MethodNotAllowedException { String resourceStateId = getResourceStateId(httpMethod, url); if(resourceStateId == null) { if(paths.get(url) != null) { Set<String> allowedMethods = paths.get(url).keySet(); throw new MethodNotAllowedException(allowedMethods); } else { return null; } } return getResourceState(resourceStateId); } @Override public String getResourceStateId(String httpMethod, String url) throws MethodNotAllowedException { Map<String,String> methodToState = null; methodToState = paths.get(url); String resourceStateId = null; if(methodToState != null) { resourceStateId = methodToState.get(httpMethod); if(resourceStateId == null) { if(paths.get(url) != null) { Set<String> allowedMethods = paths.get(url).keySet(); throw new MethodNotAllowedException(allowedMethods); } } } else { return null; } return resourceStateId; } }