001/* 002 * #%L 003 * Netarchivesuite - harvester 004 * %% 005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library, 006 * the National Library of France and the Austrian National Library. 007 * %% 008 * This program is free software: you can redistribute it and/or modify 009 * it under the terms of the GNU Lesser General Public License as 010 * published by the Free Software Foundation, either version 2.1 of the 011 * License, or (at your option) any later version. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Lesser Public License for more details. 017 * 018 * You should have received a copy of the GNU General Lesser Public 019 * License along with this program. If not, see 020 * <http://www.gnu.org/licenses/lgpl-2.1.html>. 021 * #L% 022 */ 023 024package dk.netarkivet.harvester.datamodel.extendedfield; 025 026import java.text.DecimalFormat; 027import java.text.ParseException; 028import java.text.SimpleDateFormat; 029import java.util.TimeZone; 030 031import org.slf4j.Logger; 032import org.slf4j.LoggerFactory; 033 034import dk.netarkivet.common.exceptions.ArgumentNotValid; 035 036/** 037 * Class for constructing, validating, and keeping the default value for a single ExtendedField. 038 */ 039public class ExtendedFieldDefaultValue { 040 041 /** The logger. */ 042 private static final Logger log = LoggerFactory.getLogger(ExtendedFieldDefaultValue.class); 043 044 /** Array of strings considered to be "true" values. */ 045 protected static final String[] possibleTrueValues = {"true", "t", "1"}; 046 /** Array of strings considered to be "false" values. */ 047 protected static final String[] possibleFalseValues = {"false", "f", "0"}; 048 /** The valid state of this ExtendedFieldDefaultValue. */ 049 protected final boolean valid; 050 051 /** The value of this ExtendedFieldDefaultValue. */ 052 protected String value; 053 /** The formatting pattern of this ExtendedFieldDefaultValue. */ 054 protected String format; 055 /** The datatype of this ExtendedFieldDefaultValue. */ 056 protected int datatype; 057 058 /** 059 * Constructor for the ExtendedFieldDefaultValues class. 060 * 061 * @param aValue The given default value 062 * @param aFormat the given formatting pattern 063 * @param aDatatype the given datatype 064 */ 065 public ExtendedFieldDefaultValue(String aValue, String aFormat, int aDatatype) { 066 value = aValue; 067 format = aFormat; 068 datatype = aDatatype; 069 valid = validate(); 070 } 071 072 /** 073 * Validate the arguments to the constructor. 074 * 075 * @return true, if arguments are valid; false otherwise. 076 */ 077 private boolean validate() { 078 boolean isValid = false; 079 switch (datatype) { 080 case ExtendedFieldDataTypes.STRING: 081 isValid = true; // Any kind of string currently accepted. 082 break; 083 case ExtendedFieldDataTypes.BOOLEAN: 084 if (value != null) { // null is never a valid boolean! 085 isValid = checkBoolean(value); 086 } 087 break; 088 case ExtendedFieldDataTypes.NUMBER: 089 if (value == null || value.length() == 0) { // no value no format check 090 isValid = true; 091 break; 092 } 093 094 if (format != null) { 095 if (format.length() == 0) { 096 isValid = true; 097 break; 098 } 099 100 DecimalFormat decimalFormat = new DecimalFormat(format); 101 try { 102 decimalFormat.parse(value); 103 isValid = true; 104 } catch (ParseException e) { 105 log.debug("Invalid NUMBER: {}", value); 106 } 107 } else { 108 isValid = true; 109 } 110 break; 111 case ExtendedFieldDataTypes.TIMESTAMP: 112 case ExtendedFieldDataTypes.JSCALENDAR: 113 if (value == null || value.length() == 0) { // no value no format check 114 isValid = true; 115 break; 116 } 117 118 if (format != null) { 119 if (format.length() == 0) { 120 isValid = true; 121 break; 122 } 123 124 SimpleDateFormat dateFormat = new SimpleDateFormat(format); 125 try { 126 dateFormat.parse(value); 127 isValid = true; 128 } catch (ParseException e) { 129 log.debug("Invalid TIMESTAMP: {}", value); 130 } 131 } else { 132 isValid = true; 133 } 134 break; 135 case ExtendedFieldDataTypes.NOTE: 136 isValid = true; // Any kind of NOTE value currently accepted. 137 break; 138 case ExtendedFieldDataTypes.SELECT: 139 isValid = true; // Any kind of SELECT value currently accepted. 140 break; 141 default: 142 throw new ArgumentNotValid("Unable to validate unknown datatype: " + datatype); 143 } 144 145 return isValid; 146 } 147 148 /** 149 * Check the given string if it can be parsed as a Boolean. 150 * 151 * @param aBooleanValue A given boolean 152 * @return true, if the given string if it can be parsed as a Boolean. 153 */ 154 private static boolean checkBoolean(final String aBooleanValue) { 155 String aBooleanValueTrimmed = aBooleanValue.toLowerCase().trim(); 156 157 for (String val : possibleTrueValues) { 158 if (aBooleanValueTrimmed.equals(val)) { 159 return true; 160 } 161 } 162 163 for (String val : possibleFalseValues) { 164 if (aBooleanValueTrimmed.equals(val)) { 165 return true; 166 } 167 } 168 log.debug("The string '{}' is not a valid Boolean value", aBooleanValue); 169 return false; 170 } 171 172 /** 173 * @return true, if ExtendedFieldDefaultValue is valid, false otherwise. 174 */ 175 public boolean isValid() { 176 return valid; 177 } 178 179 /** 180 * @return String, the DB-Value of the a Value 181 */ 182 public String getDBValue() { 183 // prevent that any null value fills content column of extendedFieldValue 184 if (value == null) { 185 value = ""; 186 } 187 188 // only if datatype is Timestamp, JSCalendar or Number. Otherwise DB-Value = Value 189 if (value != null && value.length() > 0) { 190 if (ExtendedFieldDataTypes.TIMESTAMP == datatype || ExtendedFieldDataTypes.JSCALENDAR == datatype) { 191 try { 192 // the Milliseconds from 1.1.1970 will be stored as String 193 SimpleDateFormat sdf = new SimpleDateFormat(format); 194 sdf.setTimeZone(TimeZone.getTimeZone("GMT")); 195 return String.valueOf(sdf.parse(value).getTime()); 196 } catch (ParseException e) { 197 log.debug("Invalid TIMESTAMP: {}", value); 198 } 199 } else if (ExtendedFieldDataTypes.NUMBER == datatype) { 200 try { 201 // a Double Value will be stored String 202 return String.valueOf(new DecimalFormat(format).parse(value).doubleValue()); 203 } catch (ParseException e) { 204 log.debug("Invalid NUMBER: {}", value); 205 } 206 } 207 } 208 209 return value; 210 } 211 212}