/* * Copyright (C) 2014 Stefan Niederhauser (nidin@gmx.ch) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package guru.nidi.ramltester.core; import java.util.*; /** * */ public class Usage implements Iterable<Map.Entry<String, Usage.Resource>> { private final Map<String, Resource> resources = new HashMap<>(); private static <T> T getOrCreate(Class<T> clazz, Map<String, T> map, String name) { T res = map.get(name); if (res == null) { try { res = clazz.newInstance(); map.put(name, res); } catch (Exception e) { throw new RamlCheckerException("Could not create instance of " + clazz, e); } } return res; } public Resource resource(String path) { return getOrCreate(Resource.class, resources, path); } public void add(Usage usage) { for (final Map.Entry<String, Resource> resourceEntry : usage) { final Resource resource = resource(resourceEntry.getKey()); resource.incUses(resourceEntry.getValue().getUses()); for (final Map.Entry<String, Action> actionEntry : resourceEntry.getValue()) { final Action action = resource.action(actionEntry.getKey()); final Action usageAction = actionEntry.getValue(); action.incUses(usageAction.getUses()); action.addQueryParameters(usageAction.getQueryParameters()); action.addRequestHeaders(usageAction.getRequestHeaders()); action.addResponseCodes(usageAction.getResponseCodes()); for (final Map.Entry<String, Response> responseEntry : usageAction.responses()) { final Response response = action.response(responseEntry.getKey()); response.addResponseHeaders(responseEntry.getValue().getResponseHeaders()); } for (final Map.Entry<String, MimeType> mimeTypeEntry : usageAction.mimeTypes()) { final MimeType mimeType = action.mimeType(mimeTypeEntry.getKey()); mimeType.addFormParameters(mimeTypeEntry.getValue().getFormParameters()); } } } } @Override public String toString() { return "Usage" + resources; } @Override public Iterator<Map.Entry<String, Resource>> iterator() { return resources.entrySet().iterator(); } public Set<String> getUnusedResources() { final Set<String> res = new HashSet<>(); for (final Map.Entry<String, Resource> resourceEntry : this) { if (resourceEntry.getValue().getUses() == 0 && !resourceEntry.getValue().actions.isEmpty()) { res.add(resourceEntry.getKey()); } } return res; } public Set<String> getUnusedActions() { return UsageCollector.ACTION.collect(this); } public Set<String> getUnusedQueryParameters() { return UsageCollector.QUERY_PARAM.collect(this); } public Set<String> getUnusedFormParameters() { return UsageCollector.FORM_PARAM.collect(this); } public Set<String> getUnusedRequestHeaders() { return UsageCollector.REQUEST_HEADER.collect(this); } public Set<String> getUnusedResponseHeaders() { return UsageCollector.RESPONSE_HEADER.collect(this); } public Set<String> getUnusedResponseCodes() { return UsageCollector.RESPONSE_CODE.collect(this); } static class UsageBase { private int uses; public void incUses(int count) { uses += count; } public int getUses() { return uses; } } static class Resource extends UsageBase implements Iterable<Map.Entry<String, Action>> { private final Map<String, Action> actions = new HashMap<>(); public Action action(String name) { return getOrCreate(Action.class, actions, name); } @Override public String toString() { return "Resource" + actions; } @Override public Iterator<Map.Entry<String, Action>> iterator() { return actions.entrySet().iterator(); } } static class Action extends UsageBase { private final Map<String, Response> responses = new HashMap<>(); private final Map<String, MimeType> mimeTypes = new HashMap<>(); private final CountSet<String> queryParameters = new CountSet<>(); private final CountSet<String> requestHeaders = new CountSet<>(); private final CountSet<String> responseCodes = new CountSet<>(); public Response response(String name) { return getOrCreate(Response.class, responses, name); } public Iterable<Map.Entry<String, Response>> responses() { return responses.entrySet(); } public MimeType mimeType(String name) { return getOrCreate(MimeType.class, mimeTypes, name); } public Iterable<Map.Entry<String, MimeType>> mimeTypes() { return mimeTypes.entrySet(); } public void addQueryParameters(Set<String> names) { queryParameters.addAll(names); } public void initQueryParameters(Set<String> names) { queryParameters.addAll(names, 0); } public void addRequestHeaders(Set<String> names) { requestHeaders.addAll(names); } public void initRequestHeaders(Set<String> names) { requestHeaders.addAll(names, 0); } public void addResponseCode(String name) { responseCodes.add(name); } public void addResponseCodes(Set<String> names) { responseCodes.addAll(names); } public void initResponseCodes(Set<String> names) { responseCodes.addAll(names, 0); } public CountSet<String> getQueryParameters() { return queryParameters; } public CountSet<String> getRequestHeaders() { return requestHeaders; } public CountSet<String> getResponseCodes() { return responseCodes; } @Override public String toString() { return "Action{" + "responses=" + responses + ", mimeTypes=" + mimeTypes + ", queryParameters=" + queryParameters + ", requestHeaders=" + requestHeaders + ", responseCodes=" + responseCodes + '}'; } } static class Response { private final CountSet<String> responseHeaders = new CountSet<>(); public void addResponseHeaders(Set<String> names) { responseHeaders.addAll(names); } public void initResponseHeaders(Set<String> names) { responseHeaders.addAll(names, 0); } public CountSet<String> getResponseHeaders() { return responseHeaders; } @Override public String toString() { return "Response{" + "responseHeaders=" + responseHeaders + '}'; } } static class MimeType { private final CountSet<String> formParameters = new CountSet<>(); public void addFormParameters(Set<String> names) { formParameters.addAll(names); } public void initFormParameters(Set<String> names) { formParameters.addAll(names, 0); } public CountSet<String> getFormParameters() { return formParameters; } @Override public String toString() { return "MimeType{" + "formParameters=" + formParameters + '}'; } } }