top-image

OLDER ARTICLES

Hello,

Just a mini post concerning the persistence/saving of MAIL document with external/internal attachments. Here, 2 solutions for the relation between MAIL document and its attachments in Documentum.

For external attachment of MAIL document, a simple solution is the creation of dm_document/dmr_content for each external attachment and the creation of dm_relation with specific type (relation_name = ‘mail_attachment’) for the link between attachments and MAIL document:
o parent_id = r_object_id of MAIL document (dm_document -> dmr_content)
o child_id = r_object_id of attachment document (dm_document -> dmr_content)
 
DQL:

select relation_name, parent_id, child_id from dm_relation where relation_name = 'mail_attachment' and parent_id = '090xxxxxxxxcd' ;

 
 

For the internal attachment inside MAIL document (the system generates automaticaly a SHA-1 for each attachment which is stored directly in the MAIL content)
 
Exemple of MAIL document/content:

	"<item name="$FILE" seal="true" sign="true" summary="true"><object><file compression="none" encoding="unknown" flags="storedindoc" hosttype="msdos" name="1540453.htm" size="7759">
	<created><datetime>20141104T065226,37-05</datetime></created>
	<modified><datetime>20141104T065226,37-05</datetime></modified>
	<filedata>1c195c............6e83db</filedata></file></object></item>"

 
So, a solution is the creation of dm_document/dmr_content for each external attachment and the use of the storing of this SHA-1 value in the dmr_content repeating attributes content_attr_name and content_attr_value instead of the dm_relation objects.
 
The DFC javadoc contains several methods for these dmr_content repeating attributes:

o String getStringContentAttr(String name, String formatName, int page, String pageModifier) throws DfException = Return a string content attribute.
Parameters:
– name : the name of the attribute.
– formatName :the name for the content objects format.
– page : the content page.
– pageModifier : the content object’s page modifier.

o void setStringContentAttribute(String name, String value, String formatName, int page, String pageModifier) throws DfException = Set a String content attribute.
Parameters:
– name : the name of the attribute.
– value : the value of the attribute.
– formatName : the name for the content objects format.
– page : the content page.
– pageModifier : the content object’s page modifier.

 

Example:



dm_document
  r_object_id                : 090xxxxxxxxxxeef
  i_contents_id              : 060xxxxxxxxxxa84
  object_name                : binary.gif


dmr_content
  r_object_id                : 060xxxxxxxxxxa84
  parent_id               	[0]: 090xxxxxxxxxxeef
  content_attr_name       	[0]: SHA-1
				[1]: Width
				[2]: Height
				[3]: Format
				[4]: Color Mode
				[5]: Compression
				[6]: Jpeg Quality
				[7]: Gif Interleave
				[8]: Color Components
				[9]: Sample Bands
				[10]: Sample Depth
				[11]: Colorspace
  content_attr_value     	[0]: e97c9xxxxxxxxxxxxxxxxxxf36bc
				[1]: 
				[2]: 
				[3]: GIF
				[4]: Indexed
				[5]: LZW
				[6]: 
				[7]: false
				[8]: 
				[9]: 
				[10]: 
				[11]: RGB

  full_content_size          : 905

 

DQL:

select r_object_id, parent_id, content_attr_name, content_attr_value  from dmr_content where ANY (content_attr_name = 'SHA-1' and content_attr_value='1c195cxxxxxxxxxxxxxxxxxx83db' );
060xxxxxxxxx0ca	090xxxxxxxxbbe	SHA-1	1c195cxxxxxxxxxxxxxxxxxx83db

select r_object_id, r_page_cnt, r_content_size, a_content_type, i_contents_id from pwc_client_document where r_object_id ='090xxxxxxxxbbe';
090xxxxxxxxbbe	1	7759	html	060xxxxxxxxx0ca

 

Best regards,

Huseyin OZVEREN

Hi,

Juste a mini-post concerning the configuation of DATASOURCE on Documentum server.
The DATASOURCE (DS) are configurable:

 
Here, the example for the DS “java:/MY_ARCHIVE_DS” :

<?xml version='1.0' encoding='UTF-8'?>
<server xmlns="urn:jboss:domain:1.2">
    <profile>
       <subsystem xmlns="urn:jboss:domain:datasources:1.0">

            <datasources>

                <datasource jndi-name="java:/MY_ARCHIVE_DS" pool-name="MY_ARCHIVE_DS" enabled="true" use-java-context="true">
                    <connection-url>jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=MYDBSERVER123)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=MYARCHIVE)))</connection-url>
                    <driver>oracle.jdbc</driver>
                    <pool>
                        <min-pool-size>5</min-pool-size>
                        <max-pool-size>100</max-pool-size>
                    </pool>
                    <security>
                        <user-name>MY_APP_USER</user-name>
                        <password>WD{HUO/dfdfdsfdsfh]-DUHi</password>
                    </security>
                    <validation>
                        <exception-sorter class-name="org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter"/>
                    </validation>
                </datasource>
	        <drivers>
                    <driver name="h2" module="com.h2database.h2">
                        <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
                    </driver>
                    <driver name="oracle.jdbc" module="oracle.jdbc">
                        <xa-datasource-class>oracle.jdbc.xa.client.OracleXADataSource</xa-datasource-class>
                    </driver>
                    <driver name="sqljdbc" module="com.microsoft.sqlserver">
                        <driver-class>com.microsoft.sqlserver.jdbc.SQLServerDriver</driver-class>
                    </driver>
                </drivers>
            </datasources>
        </subsystem>
    </profile>

    <interfaces>

    </interfaces>

    <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">

    </socket-binding-group>
</server>

 
 
The use of this DS in the JOB/JAVA code could be:

	private static final String DS = "MY_ARCHIVE_DS";
	private static final String JNDI_PREFIX[] = { "java:/", "java:", "jdbc/" };

	//...
		InitialContext ic = new InitialContext();
		for (int i = 0; i < JNDI_PREFIX.length && dataSource == null; i++) {
			try {
				dataSource = (DataSource) ic.lookup(JNDI_PREFIX[i] + DS);
			} catch (NamingException e) {
			}
		}
		if (dataSource == null) {
			throw new Exception("Unable to find datasource " + DS);
		}
	//...

	Connection connection = dataSource.getConnection();
	try {
		connection.setAutoCommit(false);

		PreparedStatement statement = connection.prepareStatement(MessageFormat.format(sql.toString(), StringUtils.upperCase(StringUtils.trimToEmpty(table)), year.format(coll.getTime("time_stamp").getDate())));

		//... Save the original data in a BLOB field in ARCHIVE database
		Blob blob = connection.createBlob();

		//...
		statement.executeUpdate();

		//...
		blob.free();

		//...
		statement.close();

		//...

	} finally {

		if(connection!=null){
	
			if (commit) {
				connection.commit();
				println("SqlConnection transaction commited !");
			} else {
				connection.rollback();
				println("SqlConnection transaction rollbacked !");
			}
			connection.close();
		}
	}

That’s all!!!

Huseyin OZVEREN

Hi,

Here, an simple example of use of logging platform NLog in C# projects. Or course, you need add reference to Nlog package in your project via NuGet Package Manager.

NLog is a free logging platform for .NET, NETSTANDARD, Xamarin, Silverlight and Windows Phone with rich log routing and management capabilities. NLog makes it easy to produce and manage high-quality logs for your application regardless of its size or complexity.

using System;
using NLog;
using NLog.Config;
using NLog.Targets;
using System.IO;
using System.Collections.ObjectModel;
using NLog.Layouts;

namespace HuoBlog.Logging
{

    public static class LoggerService
    {
        private static Logger logger;
        private static readonly string LOGGER_TARGET_FILE_NAME = "file";

        public static string ForceNewLoggerFile(string logFilePath = null)
        {
            logger = null;
            GetLogger(logFilePath);
            return GetLogFilePath();
        }

        public static string GetLogFilePath()
        {
            string logFilePath = null;
            if(logger != null)
            {
                foreach (Target target in LogManager.Configuration.AllTargets)
                {
                    if (target.GetType() == typeof(FileTarget) 
                        && ((FileTarget)target).FileName.GetType() == typeof(SimpleLayout))
                    {
                        SimpleLayout layout = (SimpleLayout) ((FileTarget)target).FileName;
                        return layout.Text;
                    }
                }
            }

            return logFilePath;
        }

        private static Logger GetLogger(string logFilePath = null)
        {
            if (logger == null)
            {
                // Log file
                {
                    if(logFilePath == null) // Generate a logfile
                    {
                        // OLD : 
                        //string outputPath = Path.Combine(Environment.CurrentDirectory, "output");
                        //if (!Directory.Exists(outputPath))
                        //    Directory.CreateDirectory(Path.Combine(Environment.CurrentDirectory, "output"));
                        // NEW: 
                        string outputPath = Environment.CurrentDirectory;
                        logFilePath = Path.Combine(outputPath, "HuoBlog_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".log");
                    }
                }

                // Config logger
                {
                    var config = new LoggingConfiguration();
                    var fileTarget = new FileTarget();
                    fileTarget.FileName = logFilePath;
                    fileTarget.Layout = "${message}";
                    config.AddTarget(LOGGER_TARGET_FILE_NAME, fileTarget);
                    config.LoggingRules.Add(new LoggingRule("*", LogLevel.Info, fileTarget));
                    LogManager.Configuration = config;
                }

                logger = LogManager.GetLogger("Extract");
            }

            return logger;
        }

        public static void Info(string message)
        {
            GetLogger().Info("INFO: " + message);
        }

        public static void Warn(string message)
        {
            GetLogger().Warn("WARNING: " + message);
        }

        public static void Error(string message)
        {
            GetLogger().Error("ERROR: " + message);
        }

        public static void Print(string message)
        {
            GetLogger().Info(message);
        }
        
    }
}

….

try{
	string logFilePath = LoggerService.ForceNewLoggerFile();
	// ...	

	LoggerService.Info("############ HuoBlog - Started at " + DateTime.Now);
	LoggerService.Print("\n\n");
	// ...	
}
catch (Exception ex)
{
	LoggerService.Error(ex.ToString());
}
finally
{
	LoggerService.Info("############ HuoBlog - ended at " + DateTime.Now);
	// ...	
	string logFileContent = File.ReadAllText(LoggerService.GetLogFilePath());
	// ...	
}

C:\Workspaces\MS_Visual_Studio_Projects\…\bin\Debug\output\HuoBlog_20171120165730.log.

That’s all!!

Huseyin

Hi,

Here, an example to get the source folder path of CSharp class via a static method and the package System.Runtime.CompilerServices. In fact, we solicit the compiler in order to get some informations about caller (caller line number, caller method, caller file path): https://msdn.microsoft.com/fr-fr/library/system.runtime.compilerservices.callermembernameattribute(v=vs.110).aspx.

using System.IO;
using System.Runtime.CompilerServices;

namespace HuoBlog
{
    public class ModelUtility
    {
        public static string getProjectPath([CallerMemberName] string memberName = "",
                [CallerFilePath] string sourceFilePath = "",
                [CallerLineNumber] int sourceLineNumber = 0)
        {
            // new System.Diagnostics.StackTrace(true).GetFrame(0).GetFileName();
            string currentClassPath = getInternalPath();
            string currentProjectPath = Path.GetDirectoryName(currentClassPath);
            return currentProjectPath;
        }


        private static string getInternalPath([CallerMemberName] string memberName = "",
                [CallerFilePath] string sourceFilePath = "",
                [CallerLineNumber] int sourceLineNumber = 0)
        {
            return sourceFilePath;
        }
    }
}

 
…in the caller method, for example a simple Program.cs, some parameters Callerxxxx are set by compiler:

//...
string currentModelProjectPath = ModelUtility.getProjectPath();
//...
//...
// [CallerMemberName] string memberName = "Main"
// [CallerFilePath] string sourceFilePath = "C:\\Workspaces\\MS_Visual_Studio_Projects\\...\\Program.cs"
// [CallerLineNumber] int sourceLineNumber = 38

        public static string getProjectPath([CallerMemberName] string memberName = "",
                [CallerFilePath] string sourceFilePath = "",
                [CallerLineNumber] int sourceLineNumber = 0)
        {
                //...
        }
//...
//...
// [CallerMemberName] string memberName = "getProjectPath"
// [CallerFilePath] string sourceFilePath = "C:\\Workspaces\\MS_Visual_Studio_Projects\\...\\ModelUtility.cs"
// [CallerLineNumber] int sourceLineNumber = 13

        private static string getInternalPath([CallerMemberName] string memberName = "",
                [CallerFilePath] string sourceFilePath = "",
                [CallerLineNumber] int sourceLineNumber = 0)
        {
                //...
        }
//...

That’s all!!!!

Huseyin OZVEREN

Page 3 of 53:« 1 2 3 4 5 6 »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.