001/* 
002 * JKNIV, utils - Helper utilities for jdk code.
003 * 
004 * Copyright (C) 2017, the original author or authors.
005 *
006 * This library 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 2.1 of the License.
010 * 
011 * This library 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
017 * License along with this library; if not, write to the Free Software Foundation, Inc., 
018 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
019 */
020package net.sf.jkniv.reflect;
021
022import java.math.BigDecimal;
023import java.math.BigInteger;
024import java.net.URL;
025import java.util.Calendar;
026import java.util.Currency;
027import java.util.Date;
028import java.util.GregorianCalendar;
029import java.util.HashMap;
030import java.util.Map;
031import java.util.concurrent.atomic.AtomicInteger;
032import java.util.concurrent.atomic.AtomicLong;
033
034import javax.swing.JApplet;
035
036import net.sf.jkniv.asserts.Assertable;
037import net.sf.jkniv.asserts.AssertsFactory;
038import sun.util.calendar.JulianCalendar;
039
040@SuppressWarnings({"rawtypes","unchecked"})
041public class BasicType
042{
043    private static final Assertable         notNull      = AssertsFactory.getNotNull();
044    private static final BasicType          instance     = new BasicType();
045    private static final Map<String, Class> BASIC_TYPES  = new HashMap<String, Class>();
046    private static final Map<String, Class> NUMBER_TYPES = new HashMap<String, Class>();
047    
048    static
049    {
050        BASIC_TYPES.put(String.class.getCanonicalName(), String.class);
051        BASIC_TYPES.put(Integer.class.getCanonicalName(), Integer.class);
052        BASIC_TYPES.put(int.class.getCanonicalName(), int.class);
053        BASIC_TYPES.put(Long.class.getCanonicalName(), Long.class);
054        BASIC_TYPES.put(long.class.getCanonicalName(), long.class);
055        BASIC_TYPES.put(Double.class.getCanonicalName(), Double.class);
056        BASIC_TYPES.put(double.class.getCanonicalName(), double.class);
057        BASIC_TYPES.put(Float.class.getCanonicalName(), Float.class);
058        BASIC_TYPES.put(float.class.getCanonicalName(), float.class);
059        BASIC_TYPES.put(Boolean.class.getCanonicalName(), Boolean.class);
060        BASIC_TYPES.put(boolean.class.getCanonicalName(), boolean.class);
061        BASIC_TYPES.put(Date.class.getCanonicalName(), Date.class);
062        BASIC_TYPES.put(Calendar.class.getCanonicalName(), Calendar.class);
063        BASIC_TYPES.put(GregorianCalendar.class.getCanonicalName(), GregorianCalendar.class);
064        BASIC_TYPES.put(JulianCalendar.class.getCanonicalName(), JulianCalendar.class);
065        BASIC_TYPES.put(BigDecimal.class.getCanonicalName(), BigDecimal.class);
066        BASIC_TYPES.put(Short.class.getCanonicalName(), Short.class);
067        BASIC_TYPES.put(short.class.getCanonicalName(), short.class);
068        BASIC_TYPES.put(Byte.class.getCanonicalName(), Byte.class);
069        BASIC_TYPES.put(byte.class.getCanonicalName(), byte.class);
070        BASIC_TYPES.put(Character.class.getCanonicalName(), Character.class);
071        BASIC_TYPES.put(char.class.getCanonicalName(), char.class);
072        BASIC_TYPES.put(BigInteger.class.getCanonicalName(), BigInteger.class);
073        BASIC_TYPES.put(AtomicInteger.class.getCanonicalName(), AtomicInteger.class);
074        BASIC_TYPES.put(AtomicLong.class.getCanonicalName(), AtomicLong.class);
075        
076        BASIC_TYPES.put(URL.class.getCanonicalName(), URL.class);
077        BASIC_TYPES.put(Currency.class.getCanonicalName(), Currency.class);
078        
079        // new java 8 number types
080        BASIC_TYPES.put("java.util.concurrent.atomic.DoubleAccumulator", FakeJdk8Type.class);
081        BASIC_TYPES.put("java.util.concurrent.atomic.DoubleAdder", FakeJdk8Type.class);
082        BASIC_TYPES.put("java.util.concurrent.atomic.LongAccumulator", FakeJdk8Type.class);
083        BASIC_TYPES.put("java.util.concurrent.atomic.LongAdder", FakeJdk8Type.class);
084        BASIC_TYPES.put("java.time.Duration", FakeJdk8Type.class);
085        BASIC_TYPES.put("java.time.Instant", FakeJdk8Type.class);
086        BASIC_TYPES.put("java.time.LocalDate", FakeJdk8Type.class);
087        BASIC_TYPES.put("java.time.LocalDateTime", FakeJdk8Type.class);
088        BASIC_TYPES.put("java.time.LocalTime", FakeJdk8Type.class);
089        BASIC_TYPES.put("java.time.ZonedDateTime", FakeJdk8Type.class);
090        BASIC_TYPES.put("java.time.ZonaId", FakeJdk8Type.class);
091        BASIC_TYPES.put("java.time.OffsetDateTime", FakeJdk8Type.class);
092        BASIC_TYPES.put("java.time.OffsetTime", FakeJdk8Type.class);
093        
094        NUMBER_TYPES.put(Integer.class.getCanonicalName(), Integer.class);
095        NUMBER_TYPES.put(int.class.getCanonicalName(), int.class);
096        NUMBER_TYPES.put(Long.class.getCanonicalName(), Long.class);
097        NUMBER_TYPES.put(long.class.getCanonicalName(), long.class);
098        NUMBER_TYPES.put(Double.class.getCanonicalName(), Double.class);
099        NUMBER_TYPES.put(double.class.getCanonicalName(), double.class);
100        NUMBER_TYPES.put(Float.class.getCanonicalName(), Float.class);
101        NUMBER_TYPES.put(float.class.getCanonicalName(), float.class);
102        NUMBER_TYPES.put(BigDecimal.class.getCanonicalName(), BigDecimal.class);
103        NUMBER_TYPES.put(Short.class.getCanonicalName(), Short.class);
104        NUMBER_TYPES.put(short.class.getCanonicalName(), short.class);
105        NUMBER_TYPES.put(Byte.class.getCanonicalName(), Byte.class);
106        NUMBER_TYPES.put(byte.class.getCanonicalName(), byte.class);
107        NUMBER_TYPES.put(BigInteger.class.getCanonicalName(), BigInteger.class);
108        NUMBER_TYPES.put(AtomicInteger.class.getCanonicalName(), AtomicInteger.class);
109        NUMBER_TYPES.put(AtomicLong.class.getCanonicalName(), AtomicLong.class);
110        NUMBER_TYPES.put("java.util.concurrent.atomic.DoubleAccumulator", FakeJdk8Type.class);
111        NUMBER_TYPES.put("java.util.concurrent.atomic.DoubleAdder", FakeJdk8Type.class);
112        NUMBER_TYPES.put("java.util.concurrent.atomic.LongAccumulator", FakeJdk8Type.class);
113        NUMBER_TYPES.put("java.util.concurrent.atomic.LongAdder", FakeJdk8Type.class);
114        
115    }
116    
117    public static BasicType getInstance()
118    {
119        return instance;
120    }
121    
122    public boolean isNumberType(Class<?> type)
123    {
124        notNull.verify(type);
125        return NUMBER_TYPES.containsKey(type.getCanonicalName());
126    }
127    
128    /**
129     * <ul>
130     * <li>{@code String}</li>
131     * <li>{@code Integer}/{@code int}</li>
132     * <li>{@code Long}/{@code long}</li>
133     * <li>{@code Double}/{@code double}</li>
134     * <li>{@code Float}/{@code float}</li>
135     * <li>{@code Boolean}/{@code boolean}</li>
136     * <li>{@code Short}/{@code short}</li>
137     * <li>{@code Byte}/{@code byte}</li>
138     * <li>{@code Character}/{@code char}</li>
139     * <li>{@code Date}</li>
140     * <li>{@code Calendar}</li>
141     * <li>{@code GregorianCalendar}</li>
142     * <li>{@code JulianCalendar}</li>
143     * <li>{@code BigDecimal}</li>
144     * <li>{@code BigInteger}</li>
145     * <li>{@code AtomicInteger}</li>
146     * <li>{@code AtomicLong}</li>
147     * <li>{@code URL}</li>
148     * <li>{@code Currency}</li>
149     * <li>{@code DoubleAccumulator}</li>
150     * <li>{@code DoubleAdder}</li>
151     * <li>{@code LongAccumulator}</li>
152     * <li>{@code LongAdder}</li>
153     * <li>{@code Duration}</li>
154     * <li>{@code Instant}</li>
155     * <li>{@code LocalDate}</li>
156     * <li>{@code LocalDateTime}</li>
157     * <li>{@code LocalTime}</li>
158     * <li>{@code ZonedDateTime}</li>
159     * <li>{@code ZonaId}</li>
160     * <li>{@code OffsetDateTime}</li>
161     * <li>{@code OffsetTime}</li>
162     * </ul>
163     */
164    public boolean isBasicType(Class<?> type)
165    {
166        notNull.verify(type);
167        boolean answer = false;
168        Class clazz = BASIC_TYPES.get(type.getCanonicalName());
169        if (clazz == null)
170            answer = false;
171        else if (clazz.getCanonicalName().equals(FakeJdk8Type.class.getName()))
172            answer = true;
173        else
174            answer = clazz.isAssignableFrom(type);
175        return answer;
176    }
177    
178    public class FakeJdk8Type
179    {
180        String className;
181        public FakeJdk8Type(String className)
182        {
183            this.className = className;
184        }
185        
186        public boolean isAssignableFrom()
187        {
188            return true;
189        }
190    }
191}