Java tutorial
package tv.arte.resteventapi.core.presentation.decoration; /* * #%L * RestEventAPI * %% * Copyright (C) 2014 ARTE G.E.I.E * %% * This program is free software: you can redistribute it and/or modify * it under the terms of The MIT License (MIT) as published by the Open Source * Initiative. * * 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 * MIT License (MIT) for more details. * * You should have received a copy of The MIT License (MIT) * along with this program. If not, see <http://opensource.org/licenses/MIT> * #L% */ import java.lang.reflect.Method; import java.net.URI; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.servlet.http.HttpServletRequest; import org.springframework.core.convert.ConversionService; import org.springframework.hateoas.Link; import org.springframework.hateoas.core.LinkBuilderSupport; import org.springframework.hateoas.core.MappingDiscoverer; import org.springframework.hateoas.mvc.ControllerLinkBuilder; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriTemplate; /* * Code particialy copied from string-hateoas project */ /** * Builder to ease building {@link Link} instances pointing to Spring MVC controllers. * * @author Oliver Gierke * @author Kamill Sokol * @author Simeon Petev */ public class RestEventApiControllerLinkBuilder extends LinkBuilderSupport<RestEventApiControllerLinkBuilder> { private static final MappingDiscoverer DISCOVERER = new RestEventApiAnnotationMappingDiscoverer( RequestMapping.class); private UriComponentsBuilder uriBuilder; /** * Creates a new {@link ControllerLinkBuilder} using the given {@link UriComponentsBuilder}. * * @param builder must not be {@literal null}. */ protected RestEventApiControllerLinkBuilder(UriComponentsBuilder builder) { super(builder); this.uriBuilder = builder; } /* * @see org.springframework.hateoas.MethodLinkBuilderFactory#linkTo(Class<?>, Method, Object...) */ public static String linkTo(Class<?> controller, Method method, Map<String, ?> parameters, ConversionService conversionService) { Assert.notNull(controller, "Controller type must not be null!"); Assert.notNull(method, "Method must not be null!"); RestEventApiControllerLinkBuilder linkBuilder = new RestEventApiControllerLinkBuilder(getBuilder()); if (parameters == null) { parameters = new HashMap<String, Object>(1); } UriTemplate template = new UriTemplate(DISCOVERER.getMapping(controller, method)); URI uri = template.expand(parameters); linkBuilder = linkBuilder.slash(uri); List<String> templateVariables = template.getVariableNames(); for (Entry<String, ?> paramEnt : parameters.entrySet()) { if (!templateVariables.contains(paramEnt.getKey())) { String queryParamName = paramEnt.getKey(); Object queryParamValue = null; if (paramEnt.getValue() != null) { queryParamValue = conversionService.convert(paramEnt.getValue(), String.class); } if (queryParamValue != null) { linkBuilder.uriBuilder.queryParam(queryParamName, queryParamValue); } } } return linkBuilder.uriBuilder.build().toUriString(); } @Override protected RestEventApiControllerLinkBuilder getThis() { return this; } @Override protected RestEventApiControllerLinkBuilder createNewInstance(UriComponentsBuilder builder) { return new RestEventApiControllerLinkBuilder(builder); } /** * Returns a {@link UriComponentsBuilder} to continue to build the already built URI in a more fine grained way. * * @return */ public UriComponentsBuilder toUriComponentsBuilder() { return UriComponentsBuilder.fromUri(toUri()); } /** * Returns a {@link UriComponentsBuilder} obtained from the current servlet mapping with the host tweaked in case the * request contains an {@code X-Forwarded-Host} header and the scheme tweaked in case the request contains an * {@code X-Forwarded-Ssl} header * * @return */ static UriComponentsBuilder getBuilder() { HttpServletRequest request = getCurrentRequest(); ServletUriComponentsBuilder builder = ServletUriComponentsBuilder.fromServletMapping(request); String forwardedSsl = request.getHeader("X-Forwarded-Ssl"); if (StringUtils.hasText(forwardedSsl) && forwardedSsl.equalsIgnoreCase("on")) { builder.scheme("https"); } String host = request.getHeader("X-Forwarded-Host"); if (!StringUtils.hasText(host)) { return builder; } String[] hosts = StringUtils.commaDelimitedListToStringArray(host); String hostToUse = hosts[0]; if (hostToUse.contains(":")) { String[] hostAndPort = StringUtils.split(hostToUse, ":"); builder.host(hostAndPort[0]); builder.port(Integer.parseInt(hostAndPort[1])); } else { builder.host(hostToUse); builder.port(-1); // reset port if it was forwarded from default port } String port = request.getHeader("X-Forwarded-Port"); if (StringUtils.hasText(port)) { builder.port(Integer.parseInt(port)); } return builder; } /** * Copy of {@link ServletUriComponentsBuilder#getCurrentRequest()} until SPR-10110 gets fixed. * * @return */ private static HttpServletRequest getCurrentRequest() { RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); Assert.state(requestAttributes != null, "Could not find current request via RequestContextHolder"); Assert.isInstanceOf(ServletRequestAttributes.class, requestAttributes); HttpServletRequest servletRequest = ((ServletRequestAttributes) requestAttributes).getRequest(); Assert.state(servletRequest != null, "Could not find current HttpServletRequest"); return servletRequest; } }