001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    package org.apache.hadoop.hdfs.web.resources;
019    
020    import java.util.Arrays;
021    import java.util.Comparator;
022    
023    
024    /** Base class of parameters. */
025    public abstract class Param<T, D extends Param.Domain<T>> {
026      static final String NULL = "null";
027      
028      static final Comparator<Param<?,?>> NAME_CMP = new Comparator<Param<?,?>>() {
029        @Override
030        public int compare(Param<?, ?> left, Param<?, ?> right) {
031          return left.getName().compareTo(right.getName());
032        }
033      };
034    
035      /** Convert the parameters to a sorted String. */
036      public static String toSortedString(final String separator,
037          final Param<?, ?>... parameters) {
038        Arrays.sort(parameters, NAME_CMP);
039        final StringBuilder b = new StringBuilder();
040        for(Param<?, ?> p : parameters) {
041          if (p.getValue() != null) {
042            b.append(separator).append(p);
043          }
044        }
045        return b.toString();
046      }
047    
048      /** The domain of the parameter. */
049      final D domain;
050      /** The actual parameter value. */
051      final T value;
052    
053      Param(final D domain, final T value) {
054        this.domain = domain;
055        this.value = value;
056      }
057    
058      /** @return the parameter value. */
059      public final T getValue() {
060        return value;
061      }
062    
063      /** @return the parameter name. */
064      public abstract String getName();
065    
066      @Override
067      public String toString() {
068        return getName() + "=" + value;
069      }
070    
071      /** Base class of parameter domains. */
072      static abstract class Domain<T> {
073        /** Parameter name. */
074        final String paramName;
075        
076        Domain(final String paramName) {
077          this.paramName = paramName;
078        }
079     
080        /** @return the parameter name. */
081        public final String getParamName() {
082          return paramName;
083        }
084    
085        /** @return a string description of the domain of the parameter. */
086        public abstract String getDomain();
087    
088        /** @return the parameter value represented by the string. */
089        abstract T parse(String str);
090    
091        /** Parse the given string.
092         * @return the parameter value represented by the string.
093         */
094        public final T parse(final String varName, final String str) {
095          try {
096            return str != null && str.trim().length() > 0 ? parse(str) : null;
097          } catch(Exception e) {
098            throw new IllegalArgumentException("Failed to parse \"" + str
099                + "\" for the parameter " + varName
100                + ".  The value must be in the domain " + getDomain(), e);
101          }
102        }
103      }
104    }