2

I have ~30 resources each having ~10 attributes. I want to store some information about each attribute. Ex: its multiplicity, it RW (Read/Write), RO (Read only), longName, shortname.

So I was thinking of storing it in a Enum like:

public enum Attributes {

    U_RESOURCETYPE(true, "RW", "resourceType", "rt"),
    U_RESOURCEID(false, "RO", "resourceID","ri"),
    //...
}

But this lead to 300 constants (30 resources * 10 attributes).

I could also use a config file or a Singleton Enum with a Map as member.

What is the best possible way to achieve this ??

Siddharth Trikha
  • 593
  • 1
  • 7
  • 14
  • 3
    Possible duplicate of [When to use Constants vs. Config Files to maintain Configuration](http://programmers.stackexchange.com/questions/121221/when-to-use-constants-vs-config-files-to-maintain-configuration) – Matt Watson Feb 03 '16 at 11:29

2 Answers2

2

I assume these are really constants, not configuration values - i.e. they don't change between invocations or deployments.

In that case I'd store it in Java files - no complicated parsing from the config file, you can leverage type safety etc.

Your approach with enums is fine for a lot of cases, but the problem here is the number of attributes - enum constructor contains too many arguments so it's easy to get lost in them, switch order of arguments etc.

In your case I'd probably create something like this:

class Attributes {
    public static Attributes U_RESOURCETYPE = new Attributes()
            .setMultiplicity(true)
            .setRw("RW")
            .setLongName("resourceType")
            .setShortName("rt");

    public static Attributes U_RESOURCEID = new Attributes()
            .setMultiplicity(true)
            .setRw("RO")
            .setLongName("resourceID")
            .setShortName("ri");

    private boolean multiplicity;
    private String rw;
    private String longName;
    private String shortName;

    private Attributes() {}

    private Attributes setMultiplicity(boolean multiplicity) {
        this.multiplicity = multiplicity;
        return this;
    }

    private Attributes setRw(String rw) {
        this.rw = rw;
        return this;
    }

    private Attributes setLongName(String longName) {
        this.longName = longName;
        return this;
    }

    private Attributes setShortName(String shortName) {
        this.shortName = shortName;
        return this;
    }
}

It gives you typesafety and clarity, but it's a bit more laborious ...

qbd
  • 2,876
  • 1
  • 12
  • 16
  • a standard config file doesn't require any parsing. Its actually pretty straight forward. – Abhishek Tyagi Feb 09 '16 at 06:10
  • @AbhishekTyagi What do you mean? Even "standard" property files need to be parsed. – qbd Feb 09 '16 at 09:03
  • That's how: http://programmers.stackexchange.com/a/309633/113928 – Abhishek Tyagi Feb 09 '16 at 09:06
  • Properties class is not magical, it still needs to parse the config file. Disadvantage of this approach is also the fact, that all the values are untyped (strings) and you need to convert them to correct type before using them. – qbd Feb 09 '16 at 09:19
0

If you have many configuration properties across multiple application, than my recommendation would be to build a simple CCM. else its better to use config file. Here is the simplest way to load them,

Properties result = null;

  String propertyFilePath = ""//<PATH to config file>; you can manipulate with String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();

  InputStream inputStream = null;
  try {
    inputStream = new FileInputStream(propertyFilePath);
    result = new Properties();
    result.load(inputStream);
  } catch (FileNotFoundException e) {
    LOGGER.warn("Property file not found. Exception: {}",e);
  } catch (IOException e) {
    LOGGER.warn("IO Exception while reading Property File. Exception: {}",e);
  }finally {
    close(inputStream);
  }

Then you can just read a property as result.getProperty("prop1");

You can wrap this as a singleton, and call the instance for all your properties.

close is a util method for closing a stream,

public static void close(Closeable c) {
        if (c == null) return;
        try {
            c.close();
        } catch (IOException e) {
            LOGGER.warn("Exception while closing the stream, {}",e);
        }
    }