001/*
002  Licensed to the Apache Software Foundation (ASF) under one or more
003  contributor license agreements.  See the NOTICE file distributed with
004  this work for additional information regarding copyright ownership.
005  The ASF licenses this file to You under the Apache License, Version 2.0
006  (the "License"); you may not use this file except in compliance with
007  the License.  You may obtain a copy of the License at
008
009      http://www.apache.org/licenses/LICENSE-2.0
010
011  Unless required by applicable law or agreed to in writing, software
012  distributed under the License is distributed on an "AS IS" BASIS,
013  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014  See the License for the specific language governing permissions and
015  limitations under the License.
016 */
017package Apache.CLI;
018
019import java.io.File;
020import java.io.FileInputStream;
021import java.io.FileNotFoundException;
022import java.net.MalformedURLException;
023import java.net.URL;
024import java.util.Date;
025
026/**
027 * This is a temporary implementation. {@code TypeHandler} will handle the pluggableness of
028 * OptionTypes and it will direct all of these types of conversion functionalities to
029 * ConvertUtils component in Commons already. BeanUtils I think.
030 */
031@Torello.JavaDoc.JDHeaderBackgroundImg(EmbedTagFileID="LICENSE")
032public class TypeHandler
033{
034    /**
035     * Returns the class whose name is {@code className}.
036     * @param className the class name
037     * @return The class if it is found
038     * @throws ParseException if the class could not be found
039     */
040    public static Class<?> createClass(final String className) throws ParseException
041    {
042        try
043            { return Class.forName(className); }
044
045        catch (final ClassNotFoundException e)
046            { throw new ParseException("Unable to find the class: " + className); }
047    }
048
049    /**
050     * Returns the date represented by {@code str}.
051     * 
052     * <BR /><BR />This method is not yet implemented and always throws an
053     * {@code UnsupportedOperationException}.
054     *
055     * @param str the date string
056     * @return The date if {@code str} is a valid date string, otherwise return null.
057     * @throws UnsupportedOperationException always
058     */
059    public static Date createDate(final String str)
060    { throw new UnsupportedOperationException("Not yet implemented"); }
061
062    /**
063     * Returns the File represented by {@code str}.
064     * @param str the File location
065     * @return The file represented by {@code str}.
066     */
067    public static File createFile(final String str)
068    { return new File(str); }
069
070    /**
071     * Returns the File[] represented by {@code str}.
072     * 
073     * <BR /><BR />This method is not yet implemented and always throws an
074     * {@code UnsupportedOperationException}.
075     *
076     * @param str the paths to the files
077     * @return The File[] represented by {@code str}.
078     * @throws UnsupportedOperationException always
079     */
080    public static File[] createFiles(final String str)
081    {
082        // to implement/port:
083        // return FileW.findFiles(str);
084
085        throw new UnsupportedOperationException("Not yet implemented");
086    }
087
088    /**
089     * Create a number from a {@code String}. If a {@code '.'} is present, it creates a
090     * {@code Double}, otherwise a {@code Long}.
091     *
092     * @param str the value
093     * @return the number represented by {@code str}
094     * @throws ParseException if {@code str} is not a number
095     */
096    public static Number createNumber(final String str) throws ParseException
097    {
098        try
099        {
100            return (str.indexOf('.') != -1) 
101                ? Double.valueOf(str)
102                : Long.valueOf(str);
103        }
104
105        catch (final NumberFormatException e)
106            { throw new ParseException(e.getMessage()); }
107    }
108
109    /**
110     * Create an Object from the class name and empty constructor.
111     * @param className the argument value
112     * @return the initialized object
113     * @throws ParseException if the class could not be found or the object could not be created
114     */
115    public static Object createObject(final String className) throws ParseException
116    {
117        final Class<?> cl;
118
119        try
120            { cl = Class.forName(className); }
121
122        catch (final ClassNotFoundException cnfe)
123            { throw new ParseException("Unable to find the class: " + className); }
124
125        try
126            { return cl.getConstructor().newInstance(); }
127
128        catch (final Exception e)
129        {
130            throw new ParseException
131                (e.getClass().getName() + "; Unable to create an instance of: " + className);
132        }
133    }
134
135    /**
136     * Returns the URL represented by {@code str}.
137     * @param str the URL string
138     * @return The URL in {@code str} is well-formed
139     * @throws ParseException if the URL in {@code str} is not well-formed
140     */
141    public static URL createURL(final String str) throws ParseException
142    {
143        try
144            { return new URL(str); }
145
146        catch (final MalformedURLException e)
147            { throw new ParseException("Unable to parse the URL: " + str); }
148    }
149
150    /**
151     * Returns the {@code Object} of type {@code clazz} with the value of {@code str}.
152     * @param str the command line value
153     * @param clazz the class representing the type of argument
154     * @param <T> type of argument
155     * @return The instance of {@code clazz} initialized with the value of {@code str}.
156     * @throws ParseException if the value creation for the given class failed
157     */
158    @SuppressWarnings("unchecked") // returned value will have type T because it is fixed by clazz
159    public static <T> T createValue(final String str, final Class<T> clazz)
160        throws ParseException
161    {
162        if (PatternOptionBuilder.STRING_VALUE == clazz)         return (T) str;
163        if (PatternOptionBuilder.OBJECT_VALUE == clazz)         return (T) createObject(str);
164        if (PatternOptionBuilder.NUMBER_VALUE == clazz)         return (T) createNumber(str);
165        if (PatternOptionBuilder.DATE_VALUE == clazz)           return (T) createDate(str);
166        if (PatternOptionBuilder.CLASS_VALUE == clazz)          return (T) createClass(str);
167        if (PatternOptionBuilder.FILE_VALUE == clazz)           return (T) createFile(str);
168        if (PatternOptionBuilder.EXISTING_FILE_VALUE == clazz)  return (T) openFile(str);
169        if (PatternOptionBuilder.FILES_VALUE == clazz)          return (T) createFiles(str);
170        if (PatternOptionBuilder.URL_VALUE == clazz)            return (T) createURL(str);
171
172        throw new ParseException("Unable to handle the class: " + clazz);
173    }
174
175    /**
176     * Returns the {@code Object} of type {@code obj} with the value of {@code str}.
177     * @param str the command line value
178     * @param obj the type of argument
179     * @return The instance of {@code obj} initialized with the value of {@code str}.
180     * @throws ParseException if the value creation for the given object type failed
181     */
182    public static Object createValue(final String str, final Object obj)
183        throws ParseException
184    { return createValue(str, (Class<?>) obj); }
185
186    /**
187     * Returns the opened FileInputStream represented by {@code str}.
188     * @param str the file location
189     * @return The file input stream represented by {@code str}.
190     * @throws ParseException if the file is not exist or not readable
191     */
192    public static FileInputStream openFile(final String str) throws ParseException
193    {
194        try
195            { return new FileInputStream(str); }
196        
197        catch (final FileNotFoundException e)
198            { throw new ParseException("Unable to find file: " + str); }
199    }
200}