Java tutorial
/******************************************************************************* * Educational Online Test Delivery System * Copyright (c) 2013 American Institutes for Research * * Distributed under the AIR Open Source License, Version 1.0 * See accompanying file AIR-License-1_0.txt or at * http://www.smarterapp.org/documents/American_Institutes_for_Research_Open_Source_Software_License.pdf ******************************************************************************/ package org.opentestsystem.shared.progman.rest; import java.util.Map; import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import org.apache.commons.lang.StringUtils; import org.opentestsystem.shared.exception.LocalizedException; import org.opentestsystem.shared.exception.RestException; import org.opentestsystem.shared.progman.domain.Asset; import org.opentestsystem.shared.progman.domain.Asset.AssetType; import org.opentestsystem.shared.progman.domain.AssetGroup; import org.opentestsystem.shared.progman.domain.Tenant; import org.opentestsystem.shared.progman.domain.TenantChain; import org.opentestsystem.shared.progman.domain.TenantType; import org.opentestsystem.shared.progman.domain.search.AssetGroupSearchRequest; import org.opentestsystem.shared.progman.service.AssetGroupService; import org.opentestsystem.shared.progman.service.TenantChainService; import org.opentestsystem.shared.search.domain.SearchResponse; import org.opentestsystem.shared.web.AbstractRestController; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.security.access.annotation.Secured; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; @Controller @SuppressWarnings("PMD.ExcessiveImports") public class AssetGroupController extends AbstractRestController { private static final int TOTAL_COUNT_THRESHOLD = 0; @Autowired private AssetGroupService assetGroupService; @Autowired private TenantChainService tenantChainService; @Value("${pm.rest.service.endpoint}") private transient String pmBaseUrl; /** * Can query the /assetGroup endpoint with query parameters in a querystring. or with JSON. Valid parameters are: * componentName or tenantId * * @param request HttpServletRequest * @return SearchResponse<AssetGroup> */ @RequestMapping(value = "/assetGroup", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @Secured({ "ROLE_Progman Read" }) @ResponseBody public SearchResponse<AssetGroup> searchAssetGroup(final HttpServletRequest request) { AssetGroupSearchRequest searchRequest = new AssetGroupSearchRequest(request.getParameterMap()); SearchResponse<AssetGroup> searchResponse; if (searchRequest.isValid()) { searchResponse = assetGroupService.searchAssetGroups(searchRequest); } else { throw new RestException("assetGroup.search.invalidSearchCriteria"); } return searchResponse; } /** * Retrieve the /assetGroup with query parameter or with JSON (assetGroupId). * * @param request * HttpServletRequest * @return AssetGroup */ @RequestMapping(value = "/assetGroup/{assetGroupId}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE }) @Secured({ "ROLE_Progman Read" }) @ResponseBody public AssetGroup getAssetGroup(@PathVariable final String assetGroupId) { AssetGroup ret = assetGroupService.getAssetGroup(assetGroupId); populateBaseUrlForAssets(ret); return ret; } /** * Creates AssetGroup. * * @param assetGroup * to be saved. * @param response * HttpServletResponse. * @return AssetGroup newly created assetGroup object. */ @ResponseStatus(HttpStatus.CREATED) @RequestMapping(value = "/assetGroup", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = { MediaType.APPLICATION_JSON_VALUE }) @Secured({ "ROLE_Progman Admin" }) @ResponseBody public AssetGroup createAssetGroup(@RequestBody @Valid final AssetGroup assetGroup, final HttpServletResponse response) { if (StringUtils.isNotEmpty(assetGroup.getId())) { throw new LocalizedException("assetGroup.exists", new String[] { assetGroup.getId() }); } AssetGroup savedAssetGroup = assetGroupService.saveAssetGroup(assetGroup); response.setHeader("Location", savedAssetGroup.getUrl()); return savedAssetGroup; } /** * Updates AssetGroup. * * @param assetGroup * to be saved. * @param response * HttpServletResponse. * @return AssetGroup newly created assetGroup object. */ @ResponseStatus(HttpStatus.OK) @RequestMapping(value = "/assetGroup/{assetGroupId}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE, produces = { MediaType.APPLICATION_JSON_VALUE }) @Secured({ "ROLE_Progman Admin" }) @ResponseBody public AssetGroup updateAssetGroup(@PathVariable final String assetGroupId, @RequestBody @Valid final AssetGroup assetGroup, final HttpServletResponse response) { if (assetGroup == null || StringUtils.isEmpty(assetGroup.getId()) || !assetGroupId.equals(assetGroup.getId())) { throw new LocalizedException("assetGroup.invalid.id"); } AssetGroup savedAssetGroup = assetGroupService.saveAssetGroup(assetGroup); response.setHeader("Location", savedAssetGroup.getUrl()); return savedAssetGroup; } /** * Deletes AssetGroup. * * @param assetGroup * to be deleted. * @param response * HttpServletResponse. * @return AssetGroup newly created assetGroup object. */ @ResponseStatus(HttpStatus.NO_CONTENT) @RequestMapping(value = "/assetGroup/remove/{assetGroupId}", method = RequestMethod.DELETE) @Secured({ "ROLE_Progman Admin" }) public void deleteAssetGroup(@PathVariable final String assetGroupId, final HttpServletResponse response) { assetGroupService.deleteAssetGroup(assetGroupId); } /** * We want to do an Asset Group Search starting from the first result in the tenant chain * until we find a Tenant that returns assets. * This will get the Tenant Chain and walk the chain until it finds a asset group. * The chain is walked in reverse hierarchical order... so institution, district, district group, state, state group */ @ResponseStatus(HttpStatus.OK) @RequestMapping(value = "/skinnableAssets/{componentName}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE }) @Secured({ "ROLE_Progman Read" }) @ResponseBody public AssetGroup getAssetGroupForUser(@PathVariable final String componentName, final HttpServletRequest request, final HttpServletResponse response) { Map<TenantType, String> typeAndValues = TenantType.findTypes(request.getParameterMap()); TenantChain chain = tenantChainService.findTenantChain(typeAndValues); Set<Tenant> tenants = chain.getTenants(); AssetGroup group = null; if (tenants != null) { // The chain's tenants are inherently ordered from most qualified/specific to least (institution...consortium) for (Tenant myTenant : tenants) { SearchResponse<AssetGroup> groups = assetGroupService .searchAssetGroups(buildAssetGroupSearchRequest(componentName, myTenant.getId())); if (groups.getReturnCount() > TOTAL_COUNT_THRESHOLD) { group = groups.getSearchResults().get(0); if (group != null) { // once a tenant is found for the given component drop out break; } } } } if (group != null) { response.setHeader("Location", group.getUrl()); populateBaseUrlForAssets(group); } return group; } private AssetGroupSearchRequest buildAssetGroupSearchRequest(final String componentName, final String tenantId) { Map<String, String[]> groupSearch = ImmutableMap.of(AssetGroupSearchRequest.SEARCH_KEY_COMPONENT_NAME, Iterables.toArray(Lists.newArrayList(componentName), String.class), AssetGroupSearchRequest.SEARCH_KEY_TENANT_ID, Iterables.toArray(Lists.newArrayList(tenantId), String.class)); return new AssetGroupSearchRequest(groupSearch); } private void populateBaseUrlForAssets(final AssetGroup group) { if (group != null && group.getAssets() != null) { for (Asset asset : group.getAssets()) { if (AssetType.PROPERTY.equals(asset.getType())) { asset.setBasePath(""); } else { asset.setBasePath(pmBaseUrl); } } } } }