001    /*
002     * SonarQube, open source software quality management tool.
003     * Copyright (C) 2008-2014 SonarSource
004     * mailto:contact AT sonarsource DOT com
005     *
006     * SonarQube is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU Lesser General Public
008     * License as published by the Free Software Foundation; either
009     * version 3 of the License, or (at your option) any later version.
010     *
011     * SonarQube is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014     * Lesser General Public License for more details.
015     *
016     * You should have received a copy of the GNU Lesser General Public License
017     * along with this program; if not, write to the Free Software Foundation,
018     * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019     */
020    package org.sonar.api.server.ws.internal;
021    
022    import com.google.common.base.Splitter;
023    import com.google.common.collect.Lists;
024    import org.apache.commons.lang.StringUtils;
025    import org.slf4j.LoggerFactory;
026    import org.sonar.api.server.ws.Request;
027    import org.sonar.api.server.ws.WebService;
028    
029    import javax.annotation.CheckForNull;
030    import javax.annotation.Nullable;
031    
032    import java.util.List;
033    import java.util.Set;
034    
035    /**
036     * @since 4.2
037     */
038    public abstract class ValidatingRequest extends Request {
039    
040      private WebService.Action action;
041    
042      public void setAction(WebService.Action action) {
043        this.action = action;
044      }
045    
046      public WebService.Action action() {
047        return action;
048      }
049    
050      @Override
051      @CheckForNull
052      public String param(String key) {
053        return param(key, true);
054      }
055    
056      @CheckForNull
057      private String param(String key, boolean validateValue) {
058        WebService.Param definition = action.param(key);
059        String value = readParamOrDefaultValue(key, definition);
060        if (value != null && validateValue) {
061          validate(value, definition);
062        }
063        return value;
064      }
065    
066      @CheckForNull
067      @Override
068      public List<String> paramAsStrings(String key) {
069        WebService.Param definition = action.param(key);
070        String value = readParamOrDefaultValue(key, definition);
071        if (value == null) {
072          return null;
073        }
074        List<String> values = Lists.newArrayList(Splitter.on(',').omitEmptyStrings().trimResults().split(value));
075        for (String s : values) {
076          validate(s, definition);
077        }
078        return values;
079      }
080    
081      @CheckForNull
082      @Override
083      public <E extends Enum<E>> List<E> paramAsEnums(String key, Class<E> enumClass) {
084        WebService.Param definition = action.param(key);
085        String value = readParamOrDefaultValue(key, definition);
086        if (value == null) {
087          return null;
088        }
089        Iterable<String> values = Splitter.on(',').omitEmptyStrings().trimResults().split(value);
090        List<E> result = Lists.newArrayList();
091        for (String s : values) {
092          validate(s, definition);
093          result.add(Enum.valueOf(enumClass, s));
094        }
095        return result;
096      }
097    
098      @CheckForNull
099      private String readParamOrDefaultValue(String key, @Nullable WebService.Param definition) {
100        if (definition == null) {
101          String message = String.format("BUG - parameter '%s' is undefined for action '%s'", key, action.key());
102          LoggerFactory.getLogger(getClass()).error(message);
103          throw new IllegalArgumentException(message);
104        }
105        String deprecatedKey = definition.deprecatedKey();
106        String value = deprecatedKey != null ? StringUtils.defaultString(readParam(deprecatedKey), readParam(key)) : readParam(key);
107        value = StringUtils.defaultString(value, definition.defaultValue());
108        if (value == null) {
109          return null;
110        }
111        return value;
112      }
113    
114      @CheckForNull
115      protected abstract String readParam(String key);
116    
117      private void validate(String value, WebService.Param definition) {
118        Set<String> possibleValues = definition.possibleValues();
119        if (possibleValues != null && !possibleValues.contains(value)) {
120          throw new IllegalArgumentException(String.format(
121            "Value of parameter '%s' (%s) must be one of: %s", definition.key(), value, possibleValues));
122        }
123      }
124    }