Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Static Access to DataSource Field Names

    Trivial request perhaps, but wishin' I could access DataSource field names statically, e.g.,
    Code:
    DataSource dsEmployee = DataSource.get("EMPLOYEE");
    ...
    SelectItem selectName = new SelectItem(dsEmployee.NAME);
    My workaround has been to create a Java class of static field name values, which corresponds to a DataSource XML:
    Code:
    final class EMPLOYEE {
    
        // SQL COLUMN NAMES
        // RATIONALE for this approach, which may appear needlessly convoluted at first:
        // IF SQL or DataSource Field Names change, the following assignments will throw errors.
        // This is the desired behavior: We want to be notified of such changes, and adjust here centrally.
    
        protected static final String ID = "EMPLOYEE";
        private final static DataSource dsEmployee = DataSource.get(ID);
    
        protected static final String EMPLOYEE_ID = dsEmployee.getField("EMPLOYEE_ID").getName();
        protected static final String AD_ACCOUNT = dsEmployee.getField("AD_ACCOUNT").getName();
        protected static final String EMAIL = dsEmployee.getField("EMAIL").getName();
        protected static final String NAME = dsEmployee.getField("NAME").getName();
        ...
    I find this approach results in code that is easier to read and update, and ensures field-name integrity throughout the project. For me anyway.

    #2
    Can you provide a little (more) context on what you are trying to achieve?

    I think you could use an enum with all DataSource's field names (which would have some advantages over your EMPLOYEE class above in terms of clarity and functionality). Or if you just want the field list (as defined in the DataSource descriptor - .ds.xml file), you could use DataSource's getFields().

    Don't know if this is what you want/need...

    Comment


      #3
      Originally posted by carlossierra View Post
      Can you provide a little (more) context on what you are trying to achieve?

      I think you could use an enum with all DataSource's field names (which would have some advantages over your EMPLOYEE class above in terms of clarity and functionality). Or if you just want the field list (as defined in the DataSource descriptor - .ds.xml file), you could use DataSource's getFields().

      Don't know if this is what you want/need...

      Here's my evolution of thought on this:
      • At first I accessed field names as Strings, e.g., new SelectItem("NAME"); And often I can't remember the name, so I have to go look it up, again. This is particularly the case when coming back to a project I haven't touched in years.
      • Then my project grew (and grew). When I had to change a SQL column name (rare, but happens), I would search replace all occurrences of the String.
      • There's opportunity for error if I have same column name for different tables, e.g., EMPLOYEE.NAME vs. PRODUCT.NAME. I couldn't always tell at-a-glance what "NAME" referred to.
      • So then I started setting the name value once per Class, e.g., String employeeName = "NAME";, new SelectItem(employeeName);
      • But then I started getting a lot of classes, and had to change the String value in many places. Better to have them all point to a central location.
      • So I created a Class (EMPLOYEE.java) of String values that could be accessed statically, e.g., EMPLOYEE.NAME.
      • I tried ENUM, but as I recall, things like SelectItem had a type issue (they want a String, not an ENUM).
      • But in either case these values are "free-floating," they are not actually sync'ed or checked against the DataSource. This caused problems a few times, so I added the ds.getField("NAME").getName() approach to function as a check against the live DataSource.
      I'm aware of getFields(). But that returns an array of fields, which I would still have to explicitly manage.

      My thinking is this:
      • Once I load a DataSource, it "knows" which fields it has. So why not provide static access to the field *names*? The names could appear in the Content Assist menu. The IDE should provide the usual distinctive color-code format to indicate it as a static/enum value (like Alignment.CENTER, Boolean.TRUE, et al.).
      • I understand that Eclipse won't "refactor" DataSource XML field name changes across the project, but at least the old Java references will indicate an error and prompt you to update.
      • I realize I'm looking at this from the worker-bee perspective. There may be valid reasons (security?) at the framework level not to expose field names this way. I'm just expressing a desire for a nice-to-have.
      Thanks for listening!

      Comment


        #4
        I think an enum would be good for your use case. This is not for field names, but for DataSource names, but you should be able to translate the concept easily:
        Code:
        package co.focuss.bmsim.shared.types;
        
        public enum DSName {
        
            BANK_LOAD("bank_load", "Bank Load"),
            BUFFER_BANK("buffer_bank", "Buffers"),
            FAMILIES("families", "Families"),
            LOG("log", "Log"),
            USERS("users", "Users");
        
            private String id;
            private String prettyName;
        
            DSName(String id, String prettyName) {
                this.id = id;
                this.prettyName = prettyName;
            }
        
            public String getID() {
                return id;
            }
            
            public String getPrettyName() {
                return prettyName;
            }
        
            /**
             * @return a comma separated list of the DataSources used in BMSim
             */
            public static String getDSList() {
                String list = "";
                for (DSName ds: values()) {
                    list += (list.isEmpty() ? "" : ",") + ds.getID() ;
                }
                return list;
            }
        }
        You could even use the getDSList method (or in your case getFieldNameList) to create DataSources dynamically from your enums. A field name change would be trivial, since you would need to change only the respective enum property. Take into consideration that you can add more than one property to each enum, as you can see in this example, so you could have a data type property also (but bear in mind that trying to make everything as automatic as I think you want would come with some tradeoffs, as DataSource definitions couldn't be nothing but basic).

        I hope this helps, or at least gives you a different perspective on things...
        Last edited by carlossierra; 27 May 2016, 15:59.

        Comment


          #5
          Hi all,

          I also started to switch to all-enum last year.
          I also don't know if it's best practice to do so, but it is way better than simple Strings which suffer from the problems you mention. Also the usage tracking and impact analysis for a change is much easier now as you can see the usages easily in your IDE.
          Switching to enum is awful and extremely repetitive yet error prone work, but once it is complete it is definitely worth the effort.

          The same goes for String vs I18n. Now, I'd always start with I18n, even if I used only one language in the beginning.

          Best would be to have a "-free project IMHO :)

          Most annoying thing right now is that Development Mode and Tomcat don't like the introduction of new enum values / I18n methods while running as well as the fact that you have to sync the same string at three places: In your DB, in your .ds.xml and in your enum. If someone has an idea how to keep maintenance low here, I'd be happy to hear it. autoDeriveSchema might be a bit of help here for the DB/.ds.xml sync, but I do not use it, yet.

          Best regards
          Blama

          Comment


            #6
            Hi Blama. Would you care to elaborate on your main goal here (to see if I have anything to suggest):

            Originally posted by Blama View Post
            Best would be to have a "-free project IMHO :)

            Most annoying thing right now is that Development Mode and Tomcat don't like the introduction of new enum values / I18n methods while running as well as the fact that you have to sync the same string at three places: In your DB, in your .ds.xml and in your enum. If someone has an idea how to keep maintenance low here, I'd be happy to hear it. autoDeriveSchema might be a bit of help here for the DB/.ds.xml sync, but I do not use it, yet.
            What to you mean by free project? Some sort of Maven Archetype?
            And can you explain the last part also? What's your current problem with keeping your strings in sync?

            Comment


              #7
              Hi carlossierra,

              I meant "-free = quotation-mark-free (of course only in the normal java files and not in the enum-files itself). Not related to any build tool.

              My problem is that if I change a name in the DB (had to remove a typo once or translate a field I named in German instead of in English at the very start), it involves manual work. Also if I add a field to a DB-view or DB-table.
              It is clear that it is not possible to get rid of this, and it is complaining on a very high level compared to e.g. not having an IDE, a Data Modeler tool or even SmartGWT or GWT, but still, repetitive tasks do annoy.

              Best regards
              Blama

              Comment


                #8
                Ahh, ok... nothing to add then :(

                Comment

                Working...
                X