removeAttrIgnoreCase("objectclass", dataSourceAttrs); LdapEntry ldapEntry = (LdapEntry) (account instanceof LdapEntry ? account : getAccountById(account.getId()));  if (ldapEntry == null) throw AccountServiceException.NO_SUCH_ACCOUNT(account.getName());  List<DataSource> existing = getAllDataSources(account); if (existing.size() >= account.getLongAttr(A_zimbraDataSourceMaxNumEntries, 20)) throw AccountServiceException.TOO_MANY_DATA_SOURCES();  dataSourceAttrs.put(A_zimbraDataSourceName, dsName);  account.setCachedData(DATA_SOURCE_LIST_CACHE_KEY, null);  HashMap attrManagerContext = new HashMap(); AttributeManager.getInstance().preModify(dataSourceAttrs, null, attrManagerContext, true, true);  DirContext ctxt = null; try { ctxt = LdapUtil.getDirContext(true);  String dn = getDataSourceDn(ldapEntry, dsName);  Attributes attrs = new BasicAttributes(true); LdapUtil.mapToAttrs(dataSourceAttrs, attrs); Attribute oc = LdapUtil.addAttr(attrs, A_objectClass, "zimbraDataSource"); oc.add(LdapDataSource.getObjectClass(dsType));  String dsId = LdapUtil.getAttrString(attrs, A_zimbraDataSourceId); if (dsId == null) { dsId = LdapUtil.generateUUID(); attrs.put(A_zimbraDataSourceId, dsId); }  String password = LdapUtil.getAttrString(attrs, A_zimbraDataSourcePassword); if (password != null) { attrs.put(A_zimbraDataSourcePassword, DataSource.encryptData(dsId, password)); }  createSubcontext(ctxt, dn, attrs, "createDataSource");  DataSource ds = getDataSourceById(ldapEntry, dsId, ctxt); AttributeManager.getInstance().postModify(dataSourceAttrs, ds, attrManagerContext, true); return ds; } catch (NameAlreadyBoundException nabe) { throw AccountServiceException.DATA_SOURCE_EXISTS(dsName); } catch (NamingException e) { throw ServiceException.FAILURE("unable to create data source", e); } finally { LdapUtil.closeContext(ctxt); }
return createDataSource(account, dsType, dsName, dataSourceAttrs, false);
    public DataSource createDataSource(Account account, DataSource.Type dsType, String dsName, Map<String, Object> dataSourceAttrs) throws ServiceException {        removeAttrIgnoreCase("objectclass", dataSourceAttrs);            LdapEntry ldapEntry = (LdapEntry) (account instanceof LdapEntry ? account : getAccountById(account.getId()));                if (ldapEntry == null)             throw AccountServiceException.NO_SUCH_ACCOUNT(account.getName());                List<DataSource> existing = getAllDataSources(account);        if (existing.size() >= account.getLongAttr(A_zimbraDataSourceMaxNumEntries, 20))            throw AccountServiceException.TOO_MANY_DATA_SOURCES();                dataSourceAttrs.put(A_zimbraDataSourceName, dsName); // must be the same        account.setCachedData(DATA_SOURCE_LIST_CACHE_KEY, null);        HashMap attrManagerContext = new HashMap();        AttributeManager.getInstance().preModify(dataSourceAttrs, null, attrManagerContext, true, true);        DirContext ctxt = null;        try {            ctxt = LdapUtil.getDirContext(true);            String dn = getDataSourceDn(ldapEntry, dsName);            Attributes attrs = new BasicAttributes(true);            LdapUtil.mapToAttrs(dataSourceAttrs, attrs);            Attribute oc = LdapUtil.addAttr(attrs, A_objectClass, "zimbraDataSource");            oc.add(LdapDataSource.getObjectClass(dsType));                        String dsId = LdapUtil.getAttrString(attrs, A_zimbraDataSourceId);            if (dsId == null) {                dsId = LdapUtil.generateUUID();                attrs.put(A_zimbraDataSourceId, dsId);            }                        String password = LdapUtil.getAttrString(attrs, A_zimbraDataSourcePassword);            if (password != null) {                attrs.put(A_zimbraDataSourcePassword, DataSource.encryptData(dsId, password));            }            createSubcontext(ctxt, dn, attrs, "createDataSource");            DataSource ds = getDataSourceById(ldapEntry, dsId, ctxt);            AttributeManager.getInstance().postModify(dataSourceAttrs, ds, attrManagerContext, true);            return ds;        } catch (NameAlreadyBoundException nabe) {            throw AccountServiceException.DATA_SOURCE_EXISTS(dsName);        } catch (NamingException e) {            throw ServiceException.FAILURE("unable to create data source", e);        } finally {            LdapUtil.closeContext(ctxt);        }    }