001/**
002 * Copyright 2014 Tampere University of Technology, Pori Department
003 * 
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * 
008 *   http://www.apache.org/licenses/LICENSE-2.0
009 * 
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package core.tut.pori.http.parameters;
017
018import java.io.InputStream;
019import java.io.UnsupportedEncodingException;
020import java.net.URLDecoder;
021import java.util.ArrayList;
022import java.util.Iterator;
023import java.util.List;
024
025import org.apache.log4j.Logger;
026
027import core.tut.pori.http.Definitions;
028
029/**
030 * Base class for custom HTTP Parameters.
031 * 
032 * Even though the built-in parameter types should work for most cases, there might rise a need for a case-specific way to parse a given method parameter, this class is for those needs.
033 */
034public abstract class HTTPParameter {
035  private String _parameterName = null;
036
037  /**
038   * The inherited class should have no-args default constructor
039   */
040  public HTTPParameter(){
041    // nothing needed
042  }
043
044  /**
045   * Initialize the parameter by raw URL encoded string.
046   * 
047   * This can be overridden to intercept the URL encoded parameter, the default implementation decodes the string and calls initialize()
048   * 
049   * @param parameterValue
050   * @throws IllegalArgumentException
051   */
052  public void initializeRaw(String parameterValue) throws IllegalArgumentException {
053    try {
054      initialize(URLDecoder.decode(parameterValue, Definitions.ENCODING_UTF8));
055    } catch (UnsupportedEncodingException ex) {
056      Logger.getLogger(HTTPParameter.class).error(ex);  // use local variable for logger, as this exception should never be thrown
057      throw new IllegalArgumentException("Failed to decode input for parameter: "+getParameterName());  // if it does happen, abort here
058    }
059  }
060
061  /**
062   * Initialize the parameter by raw URL encoded string list.
063   * 
064   * This can be overridden to intercept the URL encoded parameter, the default implementation decodes the string and calls initialize()
065   * 
066   * @param parameterValues
067   * @throws IllegalArgumentException
068   */
069  public void initializeRaw(List<String> parameterValues) throws IllegalArgumentException {
070    List<String> retval = new ArrayList<>(parameterValues.size());  // preserve the original
071    try {
072      for(Iterator<String> iter = parameterValues.iterator();iter.hasNext();){
073        retval.add(URLDecoder.decode(iter.next(), Definitions.ENCODING_UTF8));
074      }
075      initialize(retval);
076    } catch (UnsupportedEncodingException ex) { // this should not happen
077      Logger.getLogger(HTTPParameter.class).error(ex);  // use local variable for logger, as this exception should never be thrown
078      throw new IllegalArgumentException("Failed to decode input for parameter: "+getParameterName());  // if it does happen, abort here
079    }
080  }
081
082  /**
083   * Initialize this parameter based on the given parameter values
084   * 
085   * @param parameterValues can NOT be null
086   * @throws IllegalArgumentException on bad input data
087   */
088  public abstract void initialize(List<String> parameterValues) throws IllegalArgumentException;
089
090  /**
091   * Initialize this parameter based on the given parameter value
092   * 
093   * @param parameterValue can be null
094   * @throws IllegalArgumentException on bad input data
095   */
096  public abstract void initialize(String parameterValue) throws IllegalArgumentException;
097
098  /**
099   * Initialize this parameter based on input stream
100   * 
101   * Override this method if you want to accept HTTP Body data.
102   * 
103   * The default implementation only throws an exception.
104   * 
105   * @param parameterValue can be null
106   * @throws IllegalArgumentException on bad input data
107   */
108  public void initialize(InputStream parameterValue) throws IllegalArgumentException{
109    throw new UnsupportedOperationException("The use of HTTP Body is not implemented for this parameter.");
110  }
111
112  /**
113   * 
114   * @return true if this parameter has one or more values
115   */
116  public abstract boolean hasValues();
117
118  /**
119   * 
120   * @return a single value object or null if none available
121   */
122  public abstract Object getValue();
123
124  /**
125   * @return the parameterName
126   */
127  public String getParameterName() {
128    return _parameterName;
129  }
130
131  /**
132   * @param parameterName the parameterName to set
133   */
134  public void setParameterName(String parameterName) {
135    _parameterName = parameterName;
136  }
137}