package org.ff4j.property.util; /* * #%L * ff4j-core * %% * Copyright (C) 2013 - 2015 FF4J * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ import java.lang.reflect.Constructor; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.ff4j.property.Property; import org.ff4j.property.PropertyBigDecimal; import org.ff4j.property.PropertyBigInteger; import org.ff4j.property.PropertyBoolean; import org.ff4j.property.PropertyByte; import org.ff4j.property.PropertyCalendar; import org.ff4j.property.PropertyDate; import org.ff4j.property.PropertyDouble; import org.ff4j.property.PropertyFloat; import org.ff4j.property.PropertyInt; import org.ff4j.property.PropertyLogLevel; import org.ff4j.property.PropertyLong; import org.ff4j.property.PropertyShort; import org.ff4j.property.PropertyString; import org.ff4j.utils.Util; /** * Create {@link Property} from name type and value. * * @author Cedrick Lunven (@clunven) */ public class PropertyFactory { private static Map < Class<?> , Class<?> > validPropertyPrimitives = new HashMap<Class<?>, Class<?> >(); /** * Initialized Primitive to work with Properties. */ static { validPropertyPrimitives.put(Byte.class, PropertyByte.class); validPropertyPrimitives.put(Short.class, PropertyShort.class); validPropertyPrimitives.put(Integer.class, PropertyInt.class); validPropertyPrimitives.put(Long.class, PropertyLong.class); validPropertyPrimitives.put(Double.class, PropertyDouble.class); validPropertyPrimitives.put(Boolean.class, PropertyBoolean.class); validPropertyPrimitives.put(Float.class, PropertyFloat.class); validPropertyPrimitives.put(BigInteger.class, PropertyBigInteger.class); validPropertyPrimitives.put(BigDecimal.class, PropertyBigDecimal.class); validPropertyPrimitives.put(PropertyLogLevel.LogLevel.class, PropertyLogLevel.class); validPropertyPrimitives.put(String.class, PropertyString.class); } /** * Factory method to create property. * * @param pName * property name. * @param pType * property type * @param pValue * property value * @return */ public static Property<?> createProperty(String pName, Object value) { Util.assertHasLength(pName); Util.assertNotNull(value); if (validPropertyPrimitives.containsKey(value.getClass())) { return PropertyFactory.createProperty(pName, validPropertyPrimitives.get(value.getClass()).getName(), String.valueOf(value), null, null); } if (value instanceof Date) { return PropertyFactory.createProperty(pName, PropertyDate.class.getName(), PropertyDate.SDF.format(value), null, null); } if (value instanceof Calendar) { Date valueDate = ((Calendar) value).getTime(); return PropertyFactory.createProperty(pName, PropertyCalendar.class.getName(), PropertyCalendar.SDF.format(valueDate), null, null); } if (value instanceof Property<?>) { return (Property<?>) value; } // String Value if (value.getClass().isArray() || Util.isCollection(value)) { return PropertyFactory.createProperty(pName, PropertyString.class.getName(), Util.join(Util.asCollection(value), ","), null, null); } throw new IllegalArgumentException("Cannot create property with input type " + value.getClass() + value.toString()); } /** * Factory method to create property. * * @param pName * property name. * @param pType * property type * @param pValue * property value * @return */ public static Property<?> createProperty(String pName, String pType, String pValue) { return PropertyFactory.createProperty(pName, pType, pValue, null, null); } /** * Create Property from generic bean. * * @param pgb * generic bean * @return */ public static Property<?> createProperty(PropertyJsonBean pgb) { if (pgb == null) return null; return PropertyFactory.createProperty( pgb.getName(), pgb.getType(), pgb.getValue(), pgb.getDescription(), pgb.getFixedValues()); } /** * Factory method to create property. * * @param pName * property name. * @param pType * property type * @param pValue * property value * @return */ public static Property<?> createProperty(String pName, String pType, String pValue, String desc, Set < String > fixedValues) { Util.assertNotNull(pName); Util.assertNotNull(pType); Property<?> ap = null; try { Constructor<?> constr = Class.forName(pType).getConstructor(String.class, String.class); ap = (Property<?>) constr.newInstance(pName, pValue); ap.setDescription(desc); // Is there any fixed Value ? if (fixedValues != null && !fixedValues.isEmpty()) { for (String v : fixedValues) { ap.add2FixedValueFromString(v.trim()); } // Should be filled before test if (!ap.getFixedValues().contains(ap.getValue())) { throw new IllegalArgumentException("Cannot create property <" + ap.getName() + "> invalid value <" + ap.getValue() + "> expected one of " + ap.getFixedValues()); } } return ap; } catch (Exception e) { throw new IllegalArgumentException("Cannot instantiate '" + pType + "' check default constructor : " + e.getMessage(), e); } } }