All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.vectorprint.configuration.VectorPrintProperties Maven / Gradle / Ivy

package com.vectorprint.configuration;

/*
 * #%L
 * VectorPrintConfig3.0
 * %%
 * Copyright (C) 2011 - 2013 VectorPrint
 * %%
 * 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 com.vectorprint.VectorPrintRuntimeException;
import com.vectorprint.configuration.observing.KeyValueObservable;
import com.vectorprint.configuration.observing.PrepareKeyValue;
import com.vectorprint.ArrayHelper;
import com.vectorprint.configuration.observing.KeyValue;
import com.vectorprint.configuration.observing.TrimKeyValue;
import com.vectorprint.configuration.parameters.MultipleValueParser;
import com.vectorprint.configuration.parameters.ParameterHelper;
import com.vectorprint.configuration.parser.MultiValueParser;
import com.vectorprint.configuration.parser.ParseException;
import com.vectorprint.configuration.parser.PropertiesParser;
import java.awt.Color;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PreDestroy;

/**
 * Enhances Java Map with typing, debugging info, property source, overriding properties from the command line
 * arguments. There are three sources for property values: a default value in source code, a value from a property file
 * (or url) or a value on the command line.
 *
 * @author Eduard Drenth at VectorPrint.nl
 */
public class VectorPrintProperties extends HashMap
    implements EnhancedMap, KeyValueObservable {

   private static final long serialVersionUID = 1;
   /**
    * default name of the file containing help for settings
    */
   public static final String HELPFILE = "help.properties";
   public static final String MISSINGHELP = "no help configured, provide help file " + HELPFILE + " using format =;";
   private static final Logger log = Logger.getLogger(VectorPrintProperties.class.getName());

   @Override
   public void listProperties(PrintStream ps) {
      ps.println("settings from: " + getPropertyUrl() + ":\n");
      for (Map.Entry entry : super.entrySet()) {
         ps.println(entry.getKey() + "=" + entry.getValue());
      }
      ps.println("");
   }
   private URL propertyUrl;
   private String urlString;
   private boolean allowArguments = true;
   private final Map help = new HashMap(50);
   private final Set propsFromArgs = new HashSet(10);
   private final Map> commentBeforeKeys = new HashMap>(50);
   private final List trailingComment = new ArrayList(0);

   /**
    * calls {@link #VectorPrintProperties(String, String[], java.util.List)} with properties, null, null.
    *
    * @param properties
    * @throws IOException
    * @throws com.vectorprint.configuration.parser.ParseException
    */
   public VectorPrintProperties(URL properties) throws IOException, ParseException {
      this(properties, null, null);
   }

   /**
    * calls {@link VectorPrintProperties#VectorPrintProperties(java.io.InputStream, java.lang.String, java.lang.String[], java.util.List)
    * }
    * with properties.toString for id.
    */
   public VectorPrintProperties(URL properties, String[] args, List> observers) throws IOException, ParseException {
      this(properties.openStream(), properties.toString(), observers);
   }

   /**
    * bottleneck constructor
    *
    * @param in the stream the properties will be loaded from
    * @param id the suggested id for these properties, an attempt is made to turn it into a url
    * @param observers objects responsible for preparing key value pairs being added, may be null
    * @throws IOException
    * @throws com.vectorprint.configuration.parser.ParseException
    */
   public VectorPrintProperties(InputStream in, String id, List> observers) throws IOException, ParseException {
      super(25);
      if (observers != null) {
         for (PrepareKeyValue pv : observers) {
            addObserver(pv);
         }
      }
      try {
         propertyUrl = new URL(id);
      } catch (MalformedURLException me) {
         log.warning(id + " cannot be turned into a URL");
      }
      urlString = id;
      loadFromStream(in);
   }

   /**
    * {@link ArgumentParser#parseArgs(java.lang.String[]) parses the arguments} and calls {@link #putAll(java.util.Map)
    * }
    *
    * @param args
    */
   @Override
   public void addFromArguments(String[] args) {
      if (allowArguments) {
         Map props = ArgumentParser.parseArgs(args);
         if (props != null) {
            propsFromArgs.addAll(props.keySet());
            putAll(props);
         }
      } else {
         throw new VectorPrintRuntimeException("adding properties from arguments is not allowed");
      }
   }

   /**
    * loads properties (overwrites) from the stream determined at construction. If you put a \ at the end of a line in a
    * settings file the next line will be concatenated. If there is no \ at the end and the next line contains no "="
    * the next line will be concatenated with line.separator as glue.
    *
    * @throws IOException
    */
   protected void loadFromStream(InputStream in) throws IOException, ParseException {
      BufferedReader bi = new BufferedReader(new InputStreamReader(in));
      try {
         new PropertiesParser(bi).parse(this);
      } finally {
         bi.close();
      }
   }

   /**
    * loads properties (overwrites) from the url determined at construction. If you put a \ at the end of a line in a
    * settings file the next line will be concatenated. If there is no \ at the end and the next line contains no "="
    * the next line will be concatenated with line.separator as glue.
    *
    * @see #loadFromStream(java.io.InputStream)
    * @throws IOException
    */
   protected void loadFromUrl() throws IOException, ParseException {
      loadFromStream(propertyUrl.openStream());
   }

   /**
    * save the properties to the url the properties were initialized from, including those set by
    * {@link #addFromArguments(String[])} .
    *
    * @throws IOException
    */
   public void saveToUrl() throws IOException {
      saveToUrl(propertyUrl);
   }

   public static final String EOL = System.getProperty("line.separator", "\n");

   /**
    * save the properties to a url, including those set by {@link #addFromArguments(String[])}.
    *
    * @throws IOException
    */
   public void saveToUrl(URL url) throws IOException {
      BufferedOutputStream bo = null;
      try {
         OutputStream o;
         if ("file".equals(url.getProtocol())) {
            o = new FileOutputStream(url.getFile());
         } else {
            URLConnection conn = url.openConnection();
            conn.setDoOutput(true);
            conn.setDoInput(false);
            o = conn.getOutputStream();
         }
         bo = new BufferedOutputStream(o);
         for (Map.Entry entry : super.entrySet()) {
            for (String s : getCommentBeforeKey(entry.getKey())) {
               bo.write(s.getBytes());
            }
            bo.write((entry.getKey() + "=" + entry.getValue() + EOL).getBytes());
         }
         if (!trailingComment.isEmpty()) {
            for (String s : trailingComment) {
               bo.write(s.getBytes());
            }
         }
      } finally {
         if (bo != null) {
            bo.close();
         }
      }
   }

   /**
    * calls {@link #VectorPrintProperties(String, String[], java.util.List)} with an URL constructed from the filename
    * and the arguments
    *
    * @param propertyFile
    * @param args
    * @throws IOException
    */
   public VectorPrintProperties(String propertyFile, String[] args) throws IOException, ParseException {
      this(new File(propertyFile).toURI().toURL(), args, null);
   }

   public VectorPrintProperties(String propertyFile, String[] args, List> observers) throws IOException, ParseException {
      this(new File(propertyFile).toURI().toURL(), args, observers);
   }

   /**
    * calls {@link #VectorPrintProperties(String, String[])} with an URL constructed from the filename and null
    *
    * @param propertyFile
    * @throws IOException
    */
   public VectorPrintProperties(String propertyFile) throws IOException, ParseException {
      this(propertyFile, null);
   }

   /**
    * clears all properties, reloads from the url that initialized these properties and applies the arguments provided.
    * Can be usefull when you want to reuse {@link SettingsProvider}s and/or {@link Configurable}s.
    *
    * @throws IOException
    */
   public void reset(String[] args) throws IOException, ParseException {
      clear();
      loadFromUrl();
      addFromArguments(args);
   }

   protected void debug(String key, Object val) {
      debug(key, val, true);
   }

   protected void debug(String key, Object val, boolean defaultVal) {
      if (log.isLoggable(Level.FINE)) {
         StringBuilder s = new StringBuilder(String.valueOf(val));
         if (val != null && val.getClass().isArray()) {
            s = new StringBuilder("");
            Class compType = val.getClass().getComponentType();
            if (!compType.isPrimitive()) {
               for (Object o : (Object[]) val) {
                  s.append(String.valueOf(o)).append("; ");
               }
            } else {
               if (compType.equals(boolean.class)) {
                  for (boolean o : (boolean[]) val) {
                     s.append(String.valueOf(o)).append("; ");
                  }
               } else if (compType.equals(char.class)) {
                  for (char o : (char[]) val) {
                     s.append(String.valueOf(o)).append("; ");
                  }
               } else if (compType.equals(byte.class)) {
                  for (byte o : (byte[]) val) {
                     s.append(String.valueOf(o)).append("; ");
                  }
               } else if (compType.equals(short.class)) {
                  for (short o : (short[]) val) {
                     s.append(String.valueOf(o)).append("; ");
                  }
               } else if (compType.equals(int.class)) {
                  for (int o : (int[]) val) {
                     s.append(String.valueOf(o)).append("; ");
                  }
               } else if (compType.equals(long.class)) {
                  for (long o : (long[]) val) {
                     s.append(String.valueOf(o)).append("; ");
                  }
               } else if (compType.equals(float.class)) {
                  for (float o : (float[]) val) {
                     s.append(String.valueOf(o)).append("; ");
                  }
               } else if (compType.equals(double.class)) {
                  for (double o : (double[]) val) {
                     s.append(String.valueOf(o)).append("; ");
                  }
               }
            }
         }
         log.fine(String.format("looking for property %s in %s, using value %s", key, propertyUrl, s.append((defaultVal) ? " (default)" : "").toString()));
      }
   }

   @Override
   public final String get(Object key) {
      unused.remove(key);
      return super.get(key);
   }

   @Override
   public String getProperty(String key) {
      if (log.isLoggable(Level.FINE)) {
         debug(key, (containsKey(key)) ? super.get(key) : null, false);
      }
      if (containsKey(key)) {
         return get(key);
      } else {
         return null;
      }
   }

   @Override
   public String getProperty(String key, String defaultValue) {
      if (!containsKey(key)) {
         shouldUseDefault(key, defaultValue);
         return defaultValue;
      }
      return getProperty(key);
   }

   @Override
   public URL getURLProperty(String key, URL defaultValue) throws MalformedURLException {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      return new URL(getProperty(key));
   }

   @Override
   public float getFloatProperty(String key, Float defaultValue) {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      return Float.parseFloat(getProperty(key));
   }

   @Override
   public boolean getBooleanProperty(String key, Boolean defaultValue) {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      return Boolean.parseBoolean(getProperty(key));
   }

   /**
    * determine if the default value should be used, check if it is set.
    *
    * @param key the value of key
    * @param defaultVal the value of defaultVal
    * @return true when the default value should be used
    * @throws VectorPrintRuntimeException when defaultVal should be used and is null
    */
   protected boolean shouldUseDefault(String key, Object defaultVal) throws VectorPrintRuntimeException {
      if (!containsKey(key)) {
         if (defaultVal == null) {
            throw new VectorPrintRuntimeException(key + " not found in " + propertyUrl + " and default is null");
         } else {
            debug(key, defaultVal);
            notPresent.add(key);
            return true;
         }
      } else {
         return false;
      }
   }

   @Override
   public double getDoubleProperty(String key, Double defaultValue) {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      return Double.parseDouble(getProperty(key));
   }

   @Override
   public int getIntegerProperty(String key, Integer defaultValue) {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      return Integer.parseInt(getProperty(key));
   }

   @Override
   public short getShortProperty(String key, Short defaultValue) {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      return Short.parseShort(getProperty(key));
   }

   @Override
   public char getCharProperty(String key, Character defaultValue) {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      return getProperty(key).charAt(0);
   }

   @Override
   public byte getByteProperty(String key, Byte defaultValue) {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      return Byte.decode(getProperty(key));
   }

   @Override
   public long getLongProperty(String key, Long defaultValue) {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      return Long.parseLong(getProperty(key));
   }

   @Override
   public Color getColorProperty(String key, Color defaultValue) {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      return ParameterHelper.getColorFromString(getProperty(key));
   }

   @Override
   public String[] getStringProperties(String key, String[] defaultValue) {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      try {
         return ArrayHelper.toArray(mvp.parseStringValues(getProperty(key), doTrim));
      } catch (ParseException ex) {
         throw new VectorPrintRuntimeException(ex);
      }
   }
   private transient MultipleValueParser mvp = MultipleValueParser.getInstance();

   @Override
   public URL[] getURLProperties(String key, URL[] defaultValue) throws MalformedURLException {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      try {
         return ArrayHelper.toArray(mvp.parseURLValues(getProperty(key), doTrim));
      } catch (ParseException ex) {
         throw new VectorPrintRuntimeException(ex);
      }
   }

   @Override
   public float[] getFloatProperties(String key, float[] defaultValue) {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      try {
         return ArrayHelper.unWrap(ArrayHelper.toArray(mvp.parseFloatValues(getProperty(key), doTrim)));
      } catch (ParseException ex) {
         throw new VectorPrintRuntimeException(ex);
      }
   }

   @Override
   public char[] getCharProperties(String key, char[] defaultValue) {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      try {
         return ArrayHelper.unWrap(ArrayHelper.toArray(mvp.parseCharValues(getProperty(key), doTrim)));
      } catch (ParseException ex) {
         throw new VectorPrintRuntimeException(ex);
      }
   }

   @Override
   public short[] getShortProperties(String key, short[] defaultValue) {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      try {
         return ArrayHelper.unWrap(ArrayHelper.toArray(mvp.parseShortValues(getProperty(key), doTrim)));
      } catch (ParseException ex) {
         throw new VectorPrintRuntimeException(ex);
      }
   }

   @Override
   public byte[] getByteProperties(String key, byte[] defaultValue) {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      try {
         return ArrayHelper.unWrap(ArrayHelper.toArray(mvp.parseByteValues(getProperty(key), doTrim)));
      } catch (ParseException ex) {
         throw new VectorPrintRuntimeException(ex);
      }
   }

   @Override
   public double[] getDoubleProperties(String key, double[] defaultValue) {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      try {
         return ArrayHelper.unWrap(ArrayHelper.toArray(mvp.parseDoubleValues(getProperty(key), doTrim)));
      } catch (ParseException ex) {
         throw new VectorPrintRuntimeException(ex);
      }
   }

   @Override
   public int[] getIntegerProperties(String key, int[] defaultValue) {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      try {
         return ArrayHelper.unWrap(ArrayHelper.toArray(mvp.parseIntValues(getProperty(key), doTrim)));
      } catch (ParseException ex) {
         throw new VectorPrintRuntimeException(ex);
      }
   }

   @Override
   public boolean[] getBooleanProperties(String key, boolean[] defaultValue) {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      try {
         return ArrayHelper.unWrap(ArrayHelper.toArray(mvp.parseBooleanValues(getProperty(key), doTrim)));
      } catch (ParseException ex) {
         throw new VectorPrintRuntimeException(ex);
      }
   }

   private boolean doTrim = false;

   @Override
   public Color[] getColorProperties(String key, Color[] defaultValue) {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      try {
         return ArrayHelper.toArray(mvp.parseColorValues(getProperty(key), doTrim));
      } catch (ParseException ex) {
         throw new VectorPrintRuntimeException(ex);
      }
   }

   public URL getPropertyUrl() {
      return propertyUrl;
   }

   @Override
   public boolean equals(Object obj) {
      if (obj == null) {
         return false;
      }
      if (!(obj instanceof VectorPrintProperties)) {
         return false;
      }
      final VectorPrintProperties other = (VectorPrintProperties) obj;
      return !((this.propertyUrl == null) ? (other.propertyUrl != null) : !this.propertyUrl.equals(other.propertyUrl));
   }

   @Override
   public int hashCode() {
      int hash = 3;
      hash = 37 * hash + (this.propertyUrl != null ? this.propertyUrl.hashCode() : 0);
      return hash;
   }

   public String getUrlString() {
      return urlString;
   }

   @Override
   public PropertyHelp getHelp(String key) {
      if (help.containsKey(key)) {
         return help.get(key);
      } else {
         return new PropertyHelpImpl("no help configured for " + key);
      }
   }

   /**
    * initializes help for properties
    *
    * @param help
    * @see #getHelp(java.lang.String)
    * @see #getHelp()
    */
   @Override
   public void setHelp(Map help) {
      this.help.clear();
      this.help.putAll(help);
   }

   @Override
   public Map getHelp() {
      return help;
   }

   @Override
   public String printHelp() {
      StringBuilder sb = new StringBuilder(1024);
      for (Map.Entry h : help.entrySet()) {
         sb.append(h.getKey()).append(": ").append(h.getValue().getType())
             .append("; ")
             .append(h.getValue().getExplanation())
             .append(System.getProperty("line.separator"));
      }
      return sb.toString();
   }

   /**
    * When true this property was set from {@link #addFromArguments(String[])} .
    *
    * @param key
    * @return
    */
   @Override
   public boolean isFromArguments(String key) {
      return containsKey(key) && propsFromArgs.contains(key);
   }

   @Override
   public long[] getLongProperties(String key, long[] defaultValue) {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      try {
         return ArrayHelper.unWrap(ArrayHelper.toArray(mvp.parseLongValues(getProperty(key), doTrim)));
      } catch (ParseException ex) {
         throw new VectorPrintRuntimeException(ex);
      }
   }

   @Override
   public void addObserver(PrepareKeyValue observer) {
      observers.add(observer);
      if (observer instanceof TrimKeyValue) {
         doTrim = true;
      }
   }

   @Override
   public > PKV removeObserver(PKV observer) {
      return (observers.remove(observer)) ? observer : null;
   }

   @Override
   public void prepareKeyValue(KeyValue kv) {
      for (PrepareKeyValue pkv : observers) {
         if (pkv.shouldPrepare(kv)) {
            pkv.prepare(kv);
         }
      }
   }
   private final List> observers = new LinkedList>();

   @Override
   public final String put(String key, String value) {
      KeyValue prepared = new KeyValue(key, value);
      prepareKeyValue(prepared);
      unused.add(prepared.getKey());
      return super.put(prepared.getKey(), prepared.getValue());
   }

   @Override
   public final void clear() {
      unused.clear();
      notPresent.clear();
      propsFromArgs.clear();
      trailingComment.clear();
      commentBeforeKeys.clear();
      super.clear();
   }

   @Override
   public final String remove(Object key) {
      unused.remove(key);
      propsFromArgs.remove(key);
      return super.remove(key);
   }

   private MultiValueParser sp = null;

   private MultiValueParser getParser(StringReader sr) {
      if (sp == null) {
         sp = new MultiValueParser(sr);
      } else {
         sp.ReInit(sr);
      }
      return sp;
   }

   /**
    * make a clone of the properties in the argument
    *
    * @param vp
    */
   protected VectorPrintProperties(VectorPrintProperties vp) {
      super(vp);
      init(vp);
   }

   private void init(VectorPrintProperties vp) {
      help.putAll(vp.help);
      observers.addAll(vp.observers);
      propertyUrl = vp.propertyUrl;
      propsFromArgs.addAll(vp.propsFromArgs);
      urlString = vp.urlString;
   }

   @Override
   public VectorPrintProperties clone() {
      VectorPrintProperties vp = (VectorPrintProperties) super.clone();
      init(vp);
      return vp;
   }

   /**
    *
    * @return the part of the {@link #getUrlString() url} after the last {@link File#separator}
    */
   @Override
   public String getId() {
      return urlString.substring(urlString.lastIndexOf(File.separatorChar) + 1);
   }

   /**
    * this implementation supports all primitives and their wrappers, Color, Date, URL, Class and arrays of those types.
    *
    * @param 
    * @param key
    * @param defaultValue
    * @param clazz
    * @return
    */
   @Override
   public  T getGenericProperty(String key, T defaultValue, Class clazz) {
      Object o = null;
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      try {
         if (Boolean.class.equals(clazz)||boolean.class.equals(clazz)) {
            o = Boolean.valueOf(getProperty(key));
         } else if (Color.class.equals(clazz)) {
            o = Color.decode(getProperty(key));
         } else if (Byte.class.equals(clazz)||byte.class.equals(clazz)) {
            o = Byte.decode(getProperty(key));
         } else if (Character.class.equals(clazz)||char.class.equals(clazz)) {
            o = getProperty(key).charAt(0);
         } else if (Short.class.equals(clazz)||short.class.equals(clazz)) {
            o = Short.valueOf(getProperty(key));
         } else if (Double.class.equals(clazz)||double.class.equals(clazz)) {
            o = Double.valueOf(getProperty(key));
         } else if (Float.class.equals(clazz)||float.class.equals(clazz)) {
            o = Float.valueOf(getProperty(key));
         } else if (Integer.class.equals(clazz)||int.class.equals(clazz)) {
            o = Integer.valueOf(getProperty(key));
         } else if (Long.class.equals(clazz)||long.class.equals(clazz)) {
            o = Long.valueOf(getProperty(key));
         } else if (String.class.equals(clazz)) {
            o = getProperty(key);
         } else if (URL.class.equals(clazz)) {
            try {
               o = new URL(getProperty(key));
            } catch (MalformedURLException ex) {
               throw new VectorPrintRuntimeException(ex);
            }
         } else if (Date.class.equals(clazz)) {
            try {
               o = new SimpleDateFormat().parse(getProperty(key));
            } catch (java.text.ParseException ex) {
               throw new VectorPrintRuntimeException(ex);
            }
         } else if (Class.class.equals(clazz)) {
            try {
               o = MultipleValueParser.classFromKey(getProperty(key));
            } catch (ClassNotFoundException ex) {
               throw new VectorPrintRuntimeException(ex);
            }
         } else if (String[].class.equals(clazz)) {
            o = ArrayHelper.toArray(mvp.parseStringValues(getProperty(key), doTrim));
         } else if (URL[].class.equals(clazz)) {
            o = ArrayHelper.toArray(mvp.parseURLValues(getProperty(key), doTrim));
         } else if (Float[].class.equals(clazz)) {
            o = ArrayHelper.toArray(mvp.parseFloatValues(getProperty(key), doTrim));
         } else if (float[].class.equals(clazz)) {
            o = ArrayHelper.unWrap(ArrayHelper.toArray(mvp.parseFloatValues(getProperty(key), doTrim)));
         } else if (Double[].class.equals(clazz)) {
            o = ArrayHelper.toArray(mvp.parseDoubleValues(getProperty(key), doTrim));
         } else if (double[].class.equals(clazz)) {
            o = ArrayHelper.unWrap(ArrayHelper.toArray(mvp.parseDoubleValues(getProperty(key), doTrim)));
         } else if (Short[].class.equals(clazz)) {
            o = ArrayHelper.toArray(mvp.parseShortValues(getProperty(key), doTrim));
         } else if (short[].class.equals(clazz)) {
            o = ArrayHelper.unWrap(ArrayHelper.toArray(mvp.parseShortValues(getProperty(key), doTrim)));
         } else if (Character[].class.equals(clazz)) {
            o = ArrayHelper.toArray(mvp.parseCharValues(getProperty(key), doTrim));
         } else if (char[].class.equals(clazz)) {
            o = ArrayHelper.unWrap(ArrayHelper.toArray(mvp.parseCharValues(getProperty(key), doTrim)));
         } else if (Byte[].class.equals(clazz)) {
            o = ArrayHelper.toArray(mvp.parseByteValues(getProperty(key), doTrim));
         } else if (byte[].class.equals(clazz)) {
            o = ArrayHelper.unWrap(ArrayHelper.toArray(mvp.parseByteValues(getProperty(key), doTrim)));
         } else if (Integer[].class.equals(clazz)) {
            o = ArrayHelper.toArray(mvp.parseFloatValues(getProperty(key), doTrim));
         } else if (int[].class.equals(clazz)) {
            o = ArrayHelper.unWrap(ArrayHelper.toArray(mvp.parseFloatValues(getProperty(key), doTrim)));
         } else if (Long[].class.equals(clazz)) {
            o = ArrayHelper.toArray(mvp.parseLongValues(getProperty(key), doTrim));
         } else if (long[].class.equals(clazz)) {
            o = ArrayHelper.unWrap(ArrayHelper.toArray(mvp.parseLongValues(getProperty(key), doTrim)));
         } else if (Boolean[].class.equals(clazz)) {
            o = ArrayHelper.toArray(mvp.parseBooleanValues(getProperty(key), doTrim));
         } else if (boolean[].class.equals(clazz)) {
            o = ArrayHelper.unWrap(ArrayHelper.toArray(mvp.parseBooleanValues(getProperty(key), doTrim)));
         } else if (Color[].class.equals(clazz)) {
            o = ArrayHelper.toArray(mvp.parseColorValues(getProperty(key), doTrim));
         } else if (Date[].class.equals(clazz)) {
            o = ArrayHelper.toArray(mvp.parseDateValues(getProperty(key), doTrim));
         } else if (Class[].class.equals(clazz)) {
            o = ArrayHelper.toArray(mvp.parseClassValues(getProperty(key), doTrim));
         } else {
            throw new VectorPrintRuntimeException(clazz.getName() + " not supported");
         }
      } catch (ParseException parseException) {
         throw new VectorPrintRuntimeException(parseException);
      }
      return (T) o;
   }

   public boolean isAllowArguments() {
      return allowArguments;
   }

   public VectorPrintProperties setAllowArguments(boolean allowArguments) {
      this.allowArguments = allowArguments;
      return this;
   }

   private void readObject(java.io.ObjectInputStream s)
       throws IOException, ClassNotFoundException {
      s.defaultReadObject();
      mvp = MultipleValueParser.getInstance();
   }

   @Override
   public Date getDateProperty(String key, Date defaultValue) {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      try {
         return new SimpleDateFormat().parse(getProperty(key));
      } catch (java.text.ParseException ex) {
         throw new VectorPrintRuntimeException(ex);
      }
   }

   @Override
   public Date[] getDateProperties(String key, Date[] defaultValue) {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      try {
         return ArrayHelper.toArray(mvp.parseDateValues(getProperty(key), doTrim));
      } catch (ParseException ex) {
         throw new VectorPrintRuntimeException(ex);
      }
   }

   private final Collection unused = new HashSet(25);

   @Override
   public Collection getUnusedKeys() {
      for (Iterator it = unused.iterator(); it.hasNext();) {
         String string = it.next();
         if (!containsKey(string)) {
            it.remove();
         }
      }
      // cleanup here
      return Collections.unmodifiableCollection(unused);
   }

   private final Collection notPresent = new HashSet(25);

   @Override
   public Collection getKeysNotPresent() {
      return Collections.unmodifiableCollection(notPresent);
   }

   @PreDestroy
   @Override
   protected void finalize() throws Throwable {
      log.info(String.format("Settings (%s) not used sofar: %s", getId(), getUnusedKeys()));
      log.info(String.format("Settings (%s) not present, default used: %s", getId(), getKeysNotPresent()));
   }

   @Override
   public List getCommentBeforeKey(String key) {
      if (!commentBeforeKeys.containsKey(key)) {
         commentBeforeKeys.put(key, new ArrayList(1));
      }
      return commentBeforeKeys.get(key);
   }

   @Override
   public List getTrailingComment() {
      return trailingComment;
   }

   @Override
   public EnhancedMap addCommentBeforeKey(String key, String comment) {
      if (!commentBeforeKeys.containsKey(key)) {
         commentBeforeKeys.put(key, new ArrayList(1));
      }
      commentBeforeKeys.get(key).add(comment);
      return this;
   }

   @Override
   public EnhancedMap addTrailingComment(String comment) {
      trailingComment.add(comment);
      return this;
   }

   /**
    * uses {@link MultipleValueParser#classFromKey(java.lang.String) }
    *
    * @param key
    * @param defaultValue
    * @return
    * @throws ClassNotFoundException
    */
   @Override
   public Class getClassProperty(String key, Class defaultValue) throws ClassNotFoundException {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      return MultipleValueParser.classFromKey(getProperty(key));
   }

   /**
    * uses {@link MultipleValueParser#parseClassValues(java.lang.String, boolean) }
    *
    * @param key
    * @param defaultValue
    * @return
    * @throws ClassNotFoundException
    */
   @Override
   public Class[] getClassProperties(String key, Class[] defaultValue) throws ClassNotFoundException {
      if (shouldUseDefault(key, defaultValue)) {
         return defaultValue;
      }
      try {
         return ArrayHelper.toArray(mvp.parseClassValues(getProperty(key), doTrim));
      } catch (ParseException ex) {
         throw new VectorPrintRuntimeException(ex);
      }
   }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy