top-image

LATEST ARTICLES

Hello,

I would like expose here some explanations concerning the Extended Permissions or Xpermit or r_accessor_xpermit of ACL.
 
For example, below the détails of an dm_ACL:

r_accessor_name         [0]: dm_world 	[1]: dm_owner	[2]: grp_adm	[3]: docu
r_accessor_permit       [0]: 3		[1]: 1		[2]: 6		[3]: 7
r_accessor_xpermit      [0]: 1048576	[1]: 3		[2]: 0		[3]: 0
r_is_group              [0]: F		[1]: F		[2]: T		[3]: T
r_permit_type           [0]: 0		[1]: 0		[2]: 0		[3]: 0
r_application_permit    [0]: 		[1]: 		[2]: 		[3]: 

 
Reminder:

  • dm_world = This is an alias for all of the users in a docbase.
  • dm_owner = This is an alias for the current owner of the document.
  • ACL is a regular ACL (acl_class=0 ; case of ‘dm_45%’), a template (acl_class=1) or an instance of a template (acl_class= 2). The default is zero.
  • ACLs owned by users other than the repository owner are called user ACLs. User ACLs can be public (acl_class=3) or private (acl_class=0).
  • Private ACLs can only be used by the ACL owner. User ACLs are managed by the object owner (repository owner) or superusers.


 

Presentation of Extended permissions
Extended permissions are a feature only available in version 4i and later. They greatly enhance the security capabilities of the server by letting certain users access admin functions on a per-document basis. For example, in pre-4i docbases, only two types of users could change the permissions on a document: the owner of that document and a superuser. In 4i, you can use the extended permissions to allow certain normal users to change the permissions.
For example, an ACL for the Marketing department might allow the marketing_managers group to change the permissions on the document.

 
The extended permissions are described below:

  • execute_proc: Allows the user to execute the procedure (if it is a procedure)
  • change_location: Allows the user to change the location of the document.
  • change_state: Allows the user to change the state of the document using the document lifecycle.
  • change_permit: Allows the user to change the object’s permissions.
  • change_owner: Allows the user to change the owner of the object.
  • delete_object: Delete permission. Delete Object extended permission does not grant Browse, Read, Relate, Version, or Write permission.
  • change_folder_links: Allows the user to create a document in a folder without having the write right on this folder.

 
More the Extended permissions are stored in the r_accessor_xpermit attribute of an dm_ACL. The value of this attribute is an integer that has been converted from a 4-bytes binary number (or 32-bits binary number) to a decimal number. Each permission is governed by the value of a bit in a particular place: 1 : signifies the permission is granted, 0 : signifies it is not.
Warning : For some reason, execute_proc and change_location are reversed, “1” signifies the permission is not granted and “0” signifies it is granted.
 
The bit locations of the extended permissions are defined like this (from right):

  • bit 01 : execute_proc
  • bit 02 : change_location
  • bit 17 : change_state
  • bit 18 : change_permissions
  • bit 19 : change_owner
  • bit 20 : extended_delete
  • bit 21 : change_folder_links

 
For conversion decimal<->binary, use the site http://www.binaryhexconverter.com/decimal-to-binary-converter.
 
 
Examples
dm_acl.r_accessor_xpermit=0:

0 => 00000000 -> 32 bits : 00000000000000000000000000000000
	- bit 01 : execute_proc ("0" warning : reverse for this permission)
	- bit 02 : change_location ("0" warning : reverse for this permission)

 
dm_acl.r_accessor_xpermit=3:

3 => 00000011 -> 32 bits : 00000000000000000000000000000011
	- none

 
dm_acl.r_accessor_xpermit=1048576:

1048576 => 100000000000000000000 -> 32 bits : 00000000000100000000000000000000
	- bit 01 : execute_proc ("0" warning : reverse for this permission)
	- bit 02 : change_location ("0" warning : reverse for this permission)
	- bit 21 : change_folder_links ("1")

 
dm_acl.r_accessor_xpermit=1048579:

1048579 => 100000000000000000011 -> 32 bits : 00000000000100000000000000000011
	- bit 21 : change_folder_links ("1")

 
 

That’s all!!!

Huseyin OZVEREN

Hello,

This post is relating to Permission Set Template (PST) or ACL Template available in Documentum. This feature is naturally coupled with Alias Set.
 
Summary: PST + Alias Set = Normal ACL
 
Concerning the theoretic aspects, I advise an excellent article highlighting that the PST feature is rarely used, probably due to developers lack of understanding and the complexity of designing security model that takes advantage of PSTs and alias sets.
 


 
A review concerning the purpose of PST and the solution with use of PSTs for a common problem (Part 1) : https://johnnygee.wordpress.com/2006/09/12/permission-set-templates-friend-or-foe-part-1/
 
Permission Set Templates – Friend or Foe? Part 1
Permission set templates (PSTs) feature has been available in Documentum for a long time now. However, it is rarely used, probably due to developers lack of understanding and the complexity of designing security model that takes advantage of PSTs and alias sets. Before deciding whether PSTs are our friend or foe (Part 2), lets review the purpose of PST (Part 1).

Problem:
Imagine you are the systems administrator for Documentum implementation. You have been told that all documents should have security permissions that satisfy this requirement:

1) Any user for a specific department can update documents that are owned by that the document; everyone else can only read the document

Lets say that there are 10 different departments (eg contracts), so the total number of ACLs you would need to create is 10. An example of this ACL would be:

contracts_acl:
dm_world – READ
contracts_dept – WRITE

This gets more complicated when you implement security in conjunction with lifecycle states. Lets say there is 3 lifecycle states – draft, approved, archived. Then, the number of ACLs you would need to create has jumped to 30 (10 depts x 3 lifecycle states = 30). An example of this would be:

contracts_draft_acl:
dm_world – READ
contracts_dept – WRITE

contracts_approved_acl:
dm_world – READ
contracts_dept – READ

contracts_archived_acl:
dm_world – NONE
contracts_dept – READ

You just spent hours creating these 30 ACLs, when you are told that

2) Any user for a specific department can update documents that are owned by that the document; everyone else cannot see it until the document is approved

3) Once a document is archived, no one (except system admins) should be able to see/search for the document – this includes users that own the document.

Arrgh! – this would require you to make changes to 20 ACLs. You would need dept_draft_acl and dept_archived_acl for each of the 10 departements (2×10=20).

 
 
Solution:
Permission set templates used in conjunction with alias sets simplifies the management of ACLs. PSTs are basically ACLs with placeholders for the accessor name – hence, thats why PSTs are sometimes called Template ACLs. These placeholders are resolved when you associate an alias set to be used with PST. The result of this is a normal ACL that the Content Server manages:

PST + Alias Set = Normal ACL

So instead of creating 30 normal ACLs for our example, you would need to create 3 PST and 10 alias sets for a total of 13 objects. An example of PST would be:

draft_acl:
dm_world – READ
%dept – WRITE

An example of alias set would be:

contracts_alias_set:
%dept – contracts_dept

When you assign alias set and PST to a document, you end up with a system managed ACL:

draft_acl:
dm_world – READ
%dept – WRITE
+
contracts_alias_set:
%dept – contracts_dept
=
system acl:
dm_world – READ
contracts_dept – WRITE

Now if you understand what I have described so far, then you can see the management advantages of PSTs. Given the new requirement #2 and #3, instead of needing to update 20 ACLs, you only need to update 2 PST. Also, if you need to add a new department, you dont have to create 3 new acls. All you need to do is create 1 new alias set.

Do you see the power now?
In Part 2, I will discuss when PSTs should/should not be used.

 


 
When should PST be used (vs regular ACLs) (Part 2): https://johnnygee.wordpress.com/2006/09/14/permission-set-templates-friend-or-foe-part-2/
Permission Set Templates – Friend or Foe? Part 2

Now that you have seen the power of PSTs, the next question you probably have is when should PST be used (vs regular ACLs).

Based on my experience, PSTs should be used when the following conditions exist – especially if ALL the conditions are true:

Your company/organization has well defined groups/roles. Examples of groups are departments and contractors. Examples of roles are content authors, managers, and vice presidents.
You plan on implementing lifecycle security. This means that permissions on documents will change over the lifecycle of the document.
You want to actively manage permissions at an enterprise level. This is important from an application support perspective. Typical end users are not knowlegable enough about Documentum security to properly dictate what permissions should be assigned to documents.
PSTs should not be used (or used sparingly) in the following situations:

Your organization is not well defined. Without some level of organization, defining meaningfull alias sets becomes very difficult.
Your organization is small and/or you do not plan to use lifecycle security. The number of PSTs or alias sets is limited, so the additional layer of complexity outweighs the benefit of PST.
Your business processes are not well defined and your security requirements are ad-hoc in nature. If the user requires the ability to grant/revoke permissions on documents at will, then you cannot manage security at a central level.
There are probably other circumstances where PSTs can be a “great friend” or an “evil foe“. I am definitely interested to hear how other architects use PSTs or have tried to use PSTs and failed given the environment they were working in.

 


 
What are the Attributes of the ACL object?
An ACL object has the following important attributes:

  • object_name: The name of the ACL which must be unique for all ALCs with the same owner_name.
  • owner_name: The owner of the ACL. System ACLs are owned by the docbase owner, while User ACLs are owned by normal docbase users.
  • r_accessor_name: A repeating attribute that lists all of the users and groups that have access.
  • r_accessor_permit: A repeating attribute that lists the level of access for each user and group defined in the accessor_name attribute.
  • r_accessor_xpermit: A repeating attribute that specifies the extended permissions for each user and group defined in the accessor_name attribute.
  • acl_class: The class of the ACL. The ACL is a regular ACL with value 0, a template ACL with value 1 (or PST), an instance of a template ACL (or PST) with value 2 or Public ACL with value 3.

 


 
Some definitions:

  • Public ACLs (acl_class=3) are available for use by any user in the repository. Public ACLs created by the repository owner are called system ACLs. System ACLs can only be managed by the repository owner. Other public ACLs can be managed by their owners or a user with Sysadmin or Superuser privileges.
  • So, a System ACL (acl_class=3 owned by repository owner) is an ACL that is created by a the repository owner and is available for all users to use. The only thing that makes it a “system” ACL is that the owner of the ACL is the same as the docbase owner. Most ACLs in a docbase should be System ACLs.
  • Private ACLs or Regular ACLs (acl_class=0) are created and owned by a user other than the repository owner. However, unlike public ACLs, private ACLs are available for use only by their owners, and only their owners or a superuser can manage them.
  • A User ACL (acl_class=0) is an ACL that is owned by a user in the docbase. It can only be used by that user. Bob can not create a document and set its permissions to one of Fred’s User ACLs. Bob can only use his own User ACLs or a System ACL.
  • An internal ACL (acl_class=0) is an ACL created on-the-fly by the server, rather than being created explicitly by a user or system administrator. An internal ACL is easy to spot because of its name which starts with “dm_45….” in the format “dm_<object_id>” like “dm_45xxxxxxxxxx108”.
  • Template ACLs or Permission Set Template (acl_class=1) are used to make applications, workflows, and lifecycles portable.For example, an application that uses a template ACL could be used by a variety of departments within an enterprise because the users or groups within the ACL entries are not defined until the ACL is assigned to an actual document.
  • Instances of Template ACL (acl_class=2) are instances of Template ACLs used with AliasSet. An instane of template ACL is easy to spot because of its name which starts with “dm_45…._800…” in the format “dm_<object_id_of_template_acl>_<suffix_of_aliasset_object_id>“. Example for instance of template ACL:
    r_object_id : 450xxxxxxxxxxx8aa
    object_name : dm_450xxxxxxxx102_800yyyyy
    acl_class : 2
    r_template_id : 450xxxxxxxx102
    r_alias_set_id : 660220c5800yyyyy

 


 

Client Capability

 
User privileges & extended privileges

  • NONE (1): A user with NONE access will never know that the document exists. They won’t see it in a folder, and if they query for it, it will not be returned in the result list. This is one of the most unique and powerful features of Documentum’s security sub-system.
  • BROWSE (2): A user with BROWSE access will be able to see the attributes of a document, but can not view the content. The user will see the document within the folder in which it lives, and the user can query for it.
  • READ (3): A user with READ access can view the attributes and content of a document, but can not annotate it, version it or edit it.
  • RELATE (4): A user with RELATE access can view the attributes and content and can annotate the content.
  • VERSION (5): A user with VERSION access can read, annotate, and create new versions of a document, but can not overwrite the current version of the document. If a user with VERSION access wants to modify the attributes of a document, he must check it out, modify the attributes, then check it in.
  • WRITE (6): A user with WRITE access can read, annotate, version, and overwrite the current document, but can not delete it. A user with WRITE access can modify the attributes of a document without checking it out.
  • DELETE (7): A user with DELETE permission can do all these things, plus delete the document. DELETE permission is the highest level of permission that a user can have on a document.


 
User permissions and extended permissions

 


 

Special Aliases
There are some special aliases :

  • dm_owner for the current owner of the document
  • dm_world for all of the users in a docbase.
  • dm_dbo to represent the docbase owner

These aliases are used to make ACLs more flexible and easier to administer.

Best regards,

Huseyin OZVEREN

Hi,

Just a mini-post concerning an utility class/helper in order to request LDAP/AD LDAPHelper:

package com.huo.lu.db.extract.ldap;

import java.io.IOException;
import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;

import com.huo.lu.db.extract.AppConstant;

/**
 * Helper in order to request LDAP/AD.
 */
public class LDAPHelper {

	private String ldapUrl = null;
	private String ldapBind = null;
	private String ldapPassword = null;
	private String searchOu = null;
	private String mfAgentSearchCriteria = null;
	private String phoneSearchCriteria = null;
	private String eMailSearchCriteria = null;
	private String nameSearchCriteria = null;
	private String adLoginSearchCriteria = null;

	private LdapContext ldapContext = null;
	private SearchControls searchCtls = null;


	public LDAPHelper(String ldapUrl, String ldapBind, String ldapPassword, String searchOu,
			String mfAgentSearchCriteria, String phoneSearchCriteria, String eMailSearchCriteria, 
			String nameSearchCriteria, String adLoginSearchCriteria) throws NamingException, IOException {

		this.initLDAP(ldapUrl, ldapBind, ldapPassword, searchOu, mfAgentSearchCriteria, phoneSearchCriteria, 
				eMailSearchCriteria, nameSearchCriteria, adLoginSearchCriteria);
	}

	
	private void initLDAP(String ldapUrl, String ldapBind, String ldapPassword, String searchOu,
			String mfAgentSearchCriteria, String phoneSearchCriteria, String eMailSearchCriteria, 
			String nameSearchCriteria, String adLoginSearchCriteria) throws NamingException, IOException {

		this.ldapUrl = ldapUrl;
		this.ldapBind = ldapBind;
		this.ldapPassword = ldapPassword;
		this.searchOu = searchOu;
		this.mfAgentSearchCriteria = mfAgentSearchCriteria;
		this.phoneSearchCriteria = phoneSearchCriteria;
		this.eMailSearchCriteria = eMailSearchCriteria;
		this.nameSearchCriteria = nameSearchCriteria;
		this.adLoginSearchCriteria = adLoginSearchCriteria;
		
		if (this.ldapUrl != null && !this.ldapUrl.equals("")) {
			Hashtable<String, String> ldapEnvironment = new Hashtable<String, String>(5);
			ldapEnvironment.put(Context.INITIAL_CONTEXT_FACTORY, AppConstant.INITIAL_CONTEXT_FACTORY);
			ldapEnvironment.put(Context.PROVIDER_URL, this.ldapUrl);
			ldapEnvironment.put(Context.SECURITY_AUTHENTICATION, AppConstant.SECURITY_AUTHENTICATION);
			ldapEnvironment.put(Context.SECURITY_PRINCIPAL, this.ldapBind);
			ldapEnvironment.put(Context.SECURITY_CREDENTIALS, this.ldapPassword);
			// Create initial context
			ldapContext = new InitialLdapContext(ldapEnvironment, null);
			searchCtls = new SearchControls();
			searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
		}
	}


		
	public void closeLDAP() throws NamingException {
		// Close the context when we're done
		ldapContext.close();
	}

	public String query(String mfUserName, String ldapResAttr) throws NamingException {
		NamingEnumeration<SearchResult> answer = getUserAttributes(mfUserName);
		return getSearchResult(answer, ldapResAttr);
	}

	public NamingEnumeration<SearchResult> getUserAttributes(String mfUserName) throws NamingException {
		NamingEnumeration<SearchResult> answer = ldapContext.search(searchOu, "(" + mfAgentSearchCriteria + "=" + mfUserName + ")", searchCtls);
		return answer;
	}

	public String getSearchResult(NamingEnumeration<SearchResult> ldapAnswer, String ldapResAttr) throws NamingException {
		String result = null;
		while (ldapAnswer.hasMore() && (result == null || result.equals(""))) {
			SearchResult sr = (SearchResult) ldapAnswer.next();
			Attributes attrs = sr.getAttributes();
			Attribute dn = attrs.get(ldapResAttr);
			if (dn != null) {
				result = (String) dn.get();
			}
			return result;
		}
		return result;
	}

	public String getSearchResult(Attributes attrs, String ldapResAttr) throws NamingException {
		String result = null;
		Attribute dn = attrs.get(ldapResAttr);
		if (dn != null) {
			result = (String) dn.get();
		}
		return result;
	}
	
	public String getPhoneNumber(String mfUserName) throws NamingException {
		return query(mfUserName, phoneSearchCriteria);
	}

	public String getPhoneNumber(NamingEnumeration<SearchResult> userAttr) throws NamingException {
		return getSearchResult(userAttr, phoneSearchCriteria);
	}

	public String getEMail(String mfUserName) throws NamingException {
		return query(mfUserName, eMailSearchCriteria);
	}

	public String getEMail(NamingEnumeration<SearchResult> userAttr) throws NamingException {
		return getSearchResult(userAttr, eMailSearchCriteria);
	}

	public String getName(String mfUserName) throws NamingException {
		return query(mfUserName, nameSearchCriteria);
	}

	public String getName(NamingEnumeration<SearchResult> userAttr) throws NamingException {
		return getSearchResult(userAttr, nameSearchCriteria);
	}

	public void finalize() {
		try {
			this.closeLDAP();
		} catch (NamingException e) {
			e.printStackTrace();
		}
	}
	
	
	public NamingEnumeration<SearchResult> getUserAttributesFromADLogin(String adLogin) throws NamingException {
		NamingEnumeration<SearchResult> answer = ldapContext.search(searchOu, "(" + adLoginSearchCriteria + "=" + adLogin + ")", searchCtls);
		return answer;
	}

}

That’s all!!!!

Huseyin OZVEREN

Hi,

Just a mini-post concerning an utility class to communicate with DCTM DCTMUtil:

package com.huo.lu.db.extract.dctm;

import java.io.IOException;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.log4j.Logger;

import com.documentum.com.DfClientX;
import com.documentum.com.IDfClientX;
import com.documentum.fc.client.DfClient;
import com.documentum.fc.client.DfQuery;
import com.documentum.fc.client.IDfClient;
import com.documentum.fc.client.IDfQuery;
import com.documentum.fc.client.IDfSession;
import com.documentum.fc.client.IDfSessionManager;
import com.documentum.fc.client.IDfType;
import com.documentum.fc.client.IDfTypedObject;
import com.documentum.fc.client.IDfValidator;
import com.documentum.fc.client.IDfValueAssistance;
import com.documentum.fc.common.DfException;
import com.documentum.fc.common.DfLoginInfo;
import com.documentum.fc.common.IDfList;
import com.documentum.fc.common.IDfLoginInfo;

/**
 * Utility class to communicate with DCTM
 */
public class DCTMUtil {
	// logger
	private static Logger LOG = Logger.getLogger(DCTMUtil.class);
	
	public DCTMUtil(){}

	/**
	 * Connect to Documentum docbase
	 * @param userName : User to connect
	 * @param passWd : password
	 * @return
	 * @throws DfException
	 */
	public IDfSessionManager connectToDocumentum(String dfcPrimaryHost, String dfcPrimaryPort, 
			String dfcGlobalRegistryRepository,
			String dfcGlobalRegistryUsername,
			String dfcGlobalRegistryPassword,
			String dfcSessionSecureConnectDefault,
			String userName, String passWd) throws DfException {
		
		IDfClientX cx = new DfClientX();
		LOG.info("Get DfClient : " + dfcPrimaryHost+ ":" + dfcPrimaryPort +"...");
		IDfClient client = cx.getLocalClient();
		LOG.info("Get DfClient : " + dfcPrimaryHost+ ":" + dfcPrimaryPort + " : done");

		// dfc.properties
		LOG.info("Get DfClientConfig : " + dfcPrimaryHost+ ":" + dfcPrimaryPort +"...");
		IDfTypedObject cfg = client.getClientConfig();
		LOG.info("Get DfClientConfig : " + dfcPrimaryHost+ ":" + dfcPrimaryPort + " : done");
		LOG.info("Set DfClientConfig.primary_host=" + dfcPrimaryHost);
		cfg.setString("primary_host", dfcPrimaryHost);
		LOG.info("Set DfClientConfig.primary_port=" + dfcPrimaryPort);
		cfg.setString("primary_port", dfcPrimaryPort);
		LOG.info("Set DfClientConfig.dfc.globalregistry.repository=" + dfcGlobalRegistryRepository);
		cfg.setString("dfc.globalregistry.repository", dfcGlobalRegistryRepository);
		LOG.info("Set DfClientConfig.dfc.globalregistry.username=" + dfcGlobalRegistryUsername);
		cfg.setString("dfc.globalregistry.username", dfcGlobalRegistryUsername);
		LOG.info("Set DfClientConfig.dfc.globalregistry.password=" + dfcGlobalRegistryPassword);
		cfg.setString("dfc.globalregistry.password", dfcGlobalRegistryPassword);
		LOG.info("Set DfClientConfig.dfc.session.secure_connect_default=" + dfcSessionSecureConnectDefault);
		cfg.setString("dfc.session.secure_connect_default", dfcSessionSecureConnectDefault);

		// documentum session manager
		LOG.info("Get SessionManager : " + dfcPrimaryHost+ ":" + dfcPrimaryPort +"...");
		IDfSessionManager sessionMgr = client.newSessionManager();
		LOG.info("Get SessionManager : " + dfcPrimaryHost+ ":" + dfcPrimaryPort + " : done");
		//sessionMgr.setLocale("fr");
		//sessionMgr.setIdentity(docbaseName, login);
		//
		// Setup login details.
		IDfLoginInfo login = new DfLoginInfo();
		login.setUser(userName);
		login.setPassword(passWd);
		//login.setDomain(null);
		//
		LOG.info("Get SessionManager.setIdentity(ALL_DOCBASES) : " + dfcPrimaryHost+ ":" + dfcPrimaryPort +" / " + userName +"...");
		sessionMgr.setIdentity(IDfSessionManager.ALL_DOCBASES, login);
		
		return sessionMgr;
	}

	/**
	 * Disconnect from documentum docbase
	 */
	public void disconnect(IDfSessionManager sessionMgr, IDfSession session) {
		if (session!=null && sessionMgr!=null) {
			LOG.info("[disconnect] Closing session ...");
			sessionMgr.release(session);
			LOG.info("[disconnect] Session closed");
			LOG.info("[disconnect] SessionMgr clearing identities ...");
			sessionMgr.clearIdentities();
			LOG.info("[disconnect] SessionMgr clear identities done");
		}
	}
	
	/**
	 * Execute une requête DQL et retourne son résultat.
	 * 
	 * @throws DfException
	 * @throws IOException
	 */
	public IDfTypedObject runDQLQuery(IDfSession session, String dqlQuery) throws Throwable {
		LOG.info("Starting runDQLQuery : "+ dqlQuery);
		IDfTypedObject objectToReturn = null;
		
		try {
			IDfQuery query = new DfQuery();
			query.setDQL(dqlQuery);
			objectToReturn = query.execute(session, IDfQuery.DF_READ_QUERY);
		} catch (Throwable th) {
			LOG.fatal("ERROR: " + ExceptionUtils.getFullStackTrace(th));
			throw th;
		}
		LOG.info("Exiting runDQLQuery : " + dqlQuery);
		return objectToReturn;
	}
	
	public String getValueMapping(IDfType type, String attrName, String attrValue) throws DfException {
		String display = attrValue;
		IDfValidator validator = type.getTypeValidator(null, "");
		IDfValueAssistance va = validator.getValueAssistance(attrName, null);
		if (va != null) {
			IDfList list = va.getActualValues();
			for (int i = 0; i < list.getCount(); i++) {
				String value = list.getString(i);
				if (value.equals(display)) {
					if (LOG.isDebugEnabled())
						LOG.info("Value: "+value);
					display = va.getDisplayValue(value);
					if (LOG.isDebugEnabled())
						LOG.info("Display: "+display);
					break;
				}
			}
		}
		return display.replace(" - ", "_");
	}

	/**
	 * Affiche les informations de connection
	 */
	public void getSessionInfo(IDfSession session) throws Throwable {
		try {
			LOG.info("");
			LOG.info("DM Session Properties: ");
			LOG.info("DM Server Version: " + session.getServerVersion());
			LOG.info("DM Session ID:     " + session.getSessionId());
			LOG.info("DFC Version:       " + DfClient.getDFCVersion());
			LOG.info("");
		} catch (Throwable th) {
			LOG.error("[getSessionInfo] Unable to retrieve DM server info: " + ExceptionUtils.getFullStackTrace(th));
			throw th;
		}
	}

}

That’s all!!!!

Huseyin OZVEREN

Page 1 of 47:1 2 3 4 »Last »
bottom-img
Copyright ® 2012 Huseyin Ozveren. No reproduction, even partial, can be used from this site and all its contents including text, documents, images, etc.. without the express permission of the author.