简体   繁体   中英

Creating a HashMap of type <String , Object>

In a previous post Creating a ToolTip Managed bean

I was able to create a manged bean to collect and display tooltip text with only a single lookup and store them in an Application Scope variable. This has worked great.

I am on the rather steep part of the JAVA learning curve so please forgive me.

I have another managed bean requirement to create a HashMap Application Scope but this time it needs to be of a type String, Object. The application is where I have a single 'master' database that contains most of the code, custom controls, and XPages. This Master Database will point to One or More application databases that will store the Notes Documents specific to the application in question. So I have created in the Master a series of Application Documents that specify the RepIDs of the Application, Help and Rules databases specific to the Application along with a number of other pieces of information about the Application. This should allow me to reuse the same custom control that will open the specific DB by passing it the Application Name. As an example the Master Design DB might point to "Purchasing", "Customer Complaints", "Travel Requests" etc. The code below works to load and store the HashMap, but I am having trouble retrieving the the data. The compiler shows two errors one at the public Object get(String key) method and the other at mapValue = this.internalMap.get(key); in the getAppRepID method I think that it is mainly syntax but not sure. I have commented the error in the code where it appears.

/**
 *This Class makes the variables that define an application within Workflo!Approval
 *available as an ApplicationScope variable. 
 */
package ca.wfsystems.wfsAppUtils;

import lotus.domino.Base;
import lotus.domino.Session;
import lotus.domino.Database;
import lotus.domino.View;
import lotus.domino.NotesException;
import lotus.domino.ViewColumn;
import lotus.domino.ViewEntry;
import lotus.domino.ViewEntryCollection;
import lotus.domino.Name;


import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import com.ibm.xsp.extlib.util.ExtLibUtil;

/**
 * @author Bill Fox Workflo Systems WFSystems.ca
 * July 2014
 * This class is provided as part of the Workflo!Approval Product
 * and can be reused within this application.
 * If copied to a different application please retain this attribution.
 *
 */
public abstract class ApplicationUtils implements Serializable, Map<String, Object> {

    private static final long serialVersionUID = 1L;
    private Session s;
    private Name serverName;
    private String repID;
    private String thisKey;
    private ViewEntryCollection formVECol;
    private Vector formNames;
    private Database thisDB;
    private Database appDB;
    private View appView;
    private View formView;
    private ViewEntry formVE;
    private ViewEntry tFormVE;
    private ViewEntry ve;
    private ViewEntry tVE;
    private ViewEntryCollection veCol;
    private final Map<String, Object> internalMap = new HashMap<String, Object>();

    public ApplicationUtils() {
        this.populateMap(internalMap);
    }

    private void populateMap(Map<String, Object> theMap) {

        try{
            s = ExtLibUtil.getCurrentSession();
            //serverName = s.createName(s.getServerName());
            thisDB = s.getCurrentDatabase();
            appView = thisDB.getView("vwWFSApplications");
            veCol = appView.getAllEntries();
            ve = veCol.getFirstEntry();
            ViewEntry tVE = null;
            while (ve != null) {
                rtnValue mapValue = new rtnValue();
                tVE = veCol.getNextEntry(ve);
                Vector colVal = ve.getColumnValues();
                thisKey = colVal.get(0).toString();
                mapValue.setRepID(colVal.get(2).toString());
                // ...... load the rest of the values .......
                theMap.put(thisKey, mapValue);  
                recycleObjects(ve);
                ve = tVE;
            }

        }catch(NotesException e){
            System.out.println(e.toString());
        }finally{
            recycleObjects(ve, veCol, appView, tVE);
        }
    }

    public class rtnValue{
        private String RepID;
        private String HelpRepID;
        private String RuleRepID;
        private Vector FormNames;


        public String getRepID() {
            return RepID;
        }
        public void setRepID(String repID) {
            RepID = repID;
        }
        public String getHelpRepID() {
            return HelpRepID;
        }
        public void setHelpRepID(String helpRepID) {
            HelpRepID = helpRepID;
        }
        public String getRuleRepID() {
            return RuleRepID;
        }
        public void setRuleRepID(String ruleRepID) {
            RuleRepID = ruleRepID;
        }
        public Vector getFormNames() {
            return FormNames;
        }
        public void setFormNames(Vector formNames) {
            FormNames = formNames;
        }
    }

    public void clear() {
        this.internalMap.clear();
        this.populateMap(this.internalMap);
    }

    public boolean containsKey(Object key) {
        return this.internalMap.containsKey(key);
    }

    public boolean containsValue(Object value) {
        return this.internalMap.containsValue(value);
    }

    public Set<java.util.Map.Entry<String, Object>> entrySet() {
        return this.internalMap.entrySet();

    }

    public Object get(String key) {
        //error on Object get Method must return a result of type Object
        try {
            if (this.internalMap.containsKey(key)) {
                return this.internalMap.get(key);
            }
        } catch (Exception e) {
            System.out.println(e.toString());
            rtnValue newMap = new rtnValue();
            return newMap;

        }

    }

    public boolean isEmpty() {
        return this.internalMap.isEmpty();
    }

    public Set<String> keySet() {
        return this.internalMap.keySet();
    }

    public Object put(String key, Object value) {
        return this.internalMap.put(key, value);
    }



    public Object remove(Object key) {
        return this.internalMap.remove(key);
    }

    public int size() {
        return this.internalMap.size();
    }

    public Collection<Object> values() {
        return this.internalMap.values();
    }

    public void putAll(Map<? extends String, ? extends Object> m) {
        this.internalMap.putAll(m);
    }

    public String getAppRepID(String key){
        /*get the Replica Id of the application database 
         * not sure this is the correct way to call this
         */
        rtnValue mapValue = new rtnValue();
        mapValue = this.internalMap.get(key);
        //error on line above Type Mismatch: can not convert Object to ApplicationUtils.rtnValue
        String repID = mapValue.getRepID();

    }
    public static void recycleObjects(Object... args) {
        for (Object o : args) {
            if (o != null) {
                if (o instanceof Base) {
                    try {
                        ((Base) o).recycle();
                    } catch (Throwable t) {
                        // who cares?
                    }
                }
            }
        }
    }
}

For the get() method, the way I handle that kind of situation is create a variable of the correct data type as null, in my try/catch set the variable, and at the end return the variable. So:

Object retVal = null;
try....
return retVal;

For the other error, if you right-click on the error marker, it might give you the opportunity to cast the variable to rtnValue, so:

mapValue = (rtnValue) this.internalMap.get(key)

If you haven't got it, Head First Java was a useful book for getting my head around some Java concepts. It's also worth downloading the FindBugs plugin for Domino Designer from OpenNTF. It will identify errors as well as bad practices. Just ignore the errors in the "local" package!

The problem is that there is an execution path that do not return nothing

public Object get(String key) {
    //error on Object get Method must return a result of type Object
    try {
        if (this.internalMap.containsKey(key)) { // false
            return this.internalMap.get(key);
        }
    } catch (Exception e) {
        System.out.println(e.toString());
        rtnValue newMap = new rtnValue();
        return newMap;

    }

}

if key is not present in the internalMap , nothing is thrown, then that method do not return anything. To fix the problem, return the newMap at the end.

public Object get(String key) {
    //error on Object get Method must return a result of type Object
    try {
        if (this.internalMap.containsKey(key)) {
            return this.internalMap.get(key);
        }
    } catch (Exception e) {
        System.out.println(e.toString());

    }
    rtnValue newMap = new rtnValue();
    return newMap;

}

You can inline the return to save the allocation (which is what the compiler will do anyway). I didn't do it just to make it clear in the example.

But still you have a compiler error in getAppRepID method. You are expecting a rtnValue but you send back an Object . You must cast there.

The appropriate way to handle this is, if you know that all values are of a given type, create the map with the proper type.

您是否尝试过将internalMap设置为rtnValue实例的映射(如此)?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM