Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Getting List of Documents with LAPI 2

Status
Not open for further replies.

mcnanuk

Programmer
Nov 10, 2011
9
DE
Hi there,

i am stuck... i am trying to get the Itemnames of Documents in my Contentserver via LAPI. My Code:

LLValue numberOfObjects = new LLValue();
doc.GetNumberOfObjects(0, 14869, numberOfObjects);
Console.WriteLine("Number of Objects " + numberOfObjects.toInteger());

LLValue node = new LLValue();
// LLValue node = (new LLValue()).setList();

doc.ListObjects(0, 14869, "DTree", "subtype=144", LAPI_DOCUMENTS.PERM_FULL, node);
LLValueEnumeration enumVal = node.enumerateValues();
while (enumVal.hasMoreElements())
{
LLValue element = (LLValue)enumVal.nextElement();


String name = element.toString("Name");
int id = element.toInteger("ID");
int pid = element.toInteger("ParentID");
int subType = element.toInteger("SubType");
Console.WriteLine("Node " + name);

}

getting the correct Count of items works fine... so basically i have a connection. so when i try to get the list, i got serveral errors. I i choose 0 as VolumeID i get an
toInteger() is not implemented for this datataype Exception
if i coose 2 or 4 as Volume Type (i got these number from my archive server) the listObjects routine works fine, but when i come to node.enumerateValues(); i got:
enumerateValues() is not implemented for this datatype

i dont know what i amm doing wrong, or if there is an other possibility to get the objects.

What i plan to do is, write a small .net programm in which i will show a Tree of some existing documents. Therefore i need the names.

thanks
mcnanuk
 
if i try:
doc.ListObjects(0, 2000, "DTree", "subtype=144", LAPI_DOCUMENTS.PERM_FULL, node);
and no document is located in my workspace i recieve a valid empty enumeration.
if i put one .txt file there... i recieve the error toInteger() not implemented ....

maybe this helps
 
Your enumeration is wrong for e.g what we are trying to do is basically try to represent header info like

dataid,parentid,subtype,ownerid
1234,1234,144,0
1567,0,0,0

when you say enumerateValue you are sitting at a value record.What you want to do is enumeratenames.The volume number really has no meaning unless you were enumerating a container object like project or discussion.archive server volumes are different and they are not known to the livelink schema.Livelink talks to archive server using http api's

See a working example concentrate on the printtypetree I have a hardcodedm objid in the example that is a container in my livelink ,and sufficient comments in the code
Code:
/*
The code albeit hard coded uses the livelink java api combined
for getting task related info
In this example execute the Live report All late workflows
Written in answer for an functional_nam query in livelink Knowledge Base
tested java version "1.3.1_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_02-b02)
OJVM Client VM (build 9.0.2.572 cdov, Copyright (c) 1998-2002  Oracle Corp., nojit)
@author K N Nair (appoos@hotmail.com) alias appnair/samalayali
kn_nair@ssa-sa.sel.sony.com in tektips
Acknowledgement  for using printTypeTree as a helper function
Fantastic object tree traversal
Glenn Heying (SCorUser8) Department: Sprint Corporate
SPRINT01 Title: Systems Developer V
E-mail: glenn.heying@mail.sprint.com Phone: (816) 665-9626
*/
package com.nairkn;
import java.util.*;
import com.opentext.api.*;
public class listObjects{
	private static String Server = "localhost"; //livelink host
	private static int Port = 2099; //livelink server port see opentext.ini
	private static String DFT = ""; //default database file or schema
	private static String User = "Admin"; //username
	private static String Pass = "Admin"; //passwd

	public static void main (String [] args)
	{
		try
		{
			//variables
			LLSession session;
                  LAPI_DOCUMENTS doc;//library object
                  LAPI_WORKFLOW flow;//workflow object
                  LLValue value=new LLValue();
		    	  session = new LLSession (Server, Port, DFT, User, Pass);
			      doc = new LAPI_DOCUMENTS (session);
                  flow= new LAPI_WORKFLOW (session);
                  LLValue LLvalueWP=new LLValue();
                  int volID, objID,versionID;
	        if (doc.AccessEnterpriseWS(value) == 0)
		        	{
		              System.out.println("Enterprise accessed");
                      objID = value.toInteger("ID");
                      volID = value.toInteger("VolumeID");
                       System.out.println("Enterprise ID: " + objID);
                       System.out.println("Enterprise Volume: " + volID);


      objID=120489;
      LLValue children=new LLValue();
      String viewName = "DTREE";
      String  queryStr="SUBTYPE=144 ";
       if (doc.ListObjects(volID,objID,viewName,queryStr,LAPI_DOCUMENTS.PERM_FULL,children )==0)
       {
	  printTypeTree(children,"|",":");
	  }
	   else
	  	{
	   				//Error Checking
	   				System.out.println("Failed to execute Document");
	   				System.out.println("Status Code: " + session.getStatus());
	   				System.out.println("Api Error: " + session.getApiError());
	   				System.out.println("Error Message: " + session.getErrMsg());
	   				System.out.println("Status Message: " + session.getStatusMessage());
			}





      }

			else
			{
				//Error Checking
				System.out.println("Failed to execute Document");
				System.out.println("Status Code: " + session.getStatus());
				System.out.println("Api Error: " + session.getApiError());
				System.out.println("Error Message: " + session.getErrMsg());
				System.out.println("Status Message: " + session.getStatusMessage());
			}





















		}
		catch (Throwable e)
		{
			System.err.println(e.getMessage() );
			e.printStackTrace (System.err);
		}
	}



//Helper class which was published by another
//user in the LAPI discussion
private static void printTypeTree(LLValue inVal, String szSep, String szName) {
		System.out.println(szSep + szName + " - " + printLLValueType(inVal.type()) + "\t" + printLLValue(inVal));
		if(inVal.type() == LLValue.LL_ASSOC ||
				inVal.type() == LLValue.LL_RECORD ||
				inVal.type() == LLValue.LL_TABLE) {
			LLNameEnumeration enumValue;
			enumValue = inVal.enumerateNames();
			while(enumValue.hasMoreElements()) {
				String elValue = enumValue.nextElement().toString();
				printTypeTree(inVal.toValue(elValue), "\t" + szSep, elValue);
			}
		}
		else {
			if(inVal.type() == LLValue.LL_LIST) {
				for(int i = 0; i < inVal.size(); i++) {
					printTypeTree(inVal.toValue(i), "\t" + szSep, "" + i);
				}
			}
		}
	}

	private static String printLLValue(LLValue llVal)
	{
		String returnString = "";

		switch (llVal.type()) {
		case LLValue.LL_BOOLEAN :
			returnString = "" + llVal.toBoolean();
			break;
		case LLValue.LL_DATE :
			returnString = llVal.toDate().toString();
			break;
		case LLValue.LL_DOUBLE :
			returnString = "" + llVal.toDouble();
			break;
		case LLValue.LL_INTEGER :
			returnString = "" + llVal.toInteger();
			break;
		case LLValue.LL_STRING :
			returnString = llVal.toString();
			break;
		default :
			break;
		}
		return returnString;
	}

	private static String printLLValueType(int iType) {
		String returnString = " ";
		switch (iType) {
		case LLValue.LL_ASSOC :
			returnString = "Type is ASSOC";
			break;
		case LLValue.LL_BOOLEAN :
			returnString = "Type is BOOLEAN";
			break;
		case LLValue.LL_DATE :
			returnString = "Type is DATE";
			break;
		case LLValue.LL_DOUBLE :
			returnString = "Type is DOUBLE";
			break;
		case LLValue.LL_ERROR :
			returnString = "Type is ERROR";
			break;
		case LLValue.LL_INTEGER :
			returnString = "Type is INTEGER";
			break;
		case LLValue.LL_LIST :
			returnString = "Type is LIST";
			break;
		case LLValue.LL_NOTSET :
			returnString = "Type is NOTSET";
			break;
		case LLValue.LL_RECORD :
			returnString = "Type is RECORD";
			break;
		case LLValue.LL_STRING :
			returnString = "Type is STRING";
			break;
		case LLValue.LL_TABLE :
			returnString = "Type is TABLE";
			break;
		case LLValue.LL_UNDEFINED :
			returnString = "Type is UNDEFINED";
			break;
		default :
			returnString = "Type is Unknown";
			break;
		}
		return returnString;
	}//helper method ends





}//class ends here


Well, if I called the wrong number, why did you answer the phone?
James Thurber, New Yorker cartoon caption, June 5, 1937
Certified OT Developer,Livelink ECM Champion 2008,Livelink ECM Champion 2010
 
Thanks....

lets say: doc.ListObjects(0, 33346, "DTree", "subtype=0", LAPI_DOCUMENTS.PERM_FULL,node);

33346 represents a folder. Within this folder are 2 files located.
What do i have to do, to get these two filenames, or mime.types


i got your code running, and it works. it gives me a list like:
|: - Type is TABLE
|VOLUMEID - Type is LIST
|PARENTID - Type is LIST
|ID - Type is LIST
|NAME - Type is LIST
|ORIGINOWNERID - Type is LIS
|ORIGINDATAID - Type is LIST
|USERID - Type is LIST
|GROUPID - Type is LIST
|USERPERM - Type is LIST
|GROUPPERM - Type is LIST
|WORLDPERM - Type is LIST
|SYSTEMPERM - Type is LIST
|ACLCOUNT - Type is LIST
|PERMID - Type is LIST
|TYPE - Type is LIST
|CREATEDBY - Type is LIST
|CREATEDATE - Type is LIST
|MODIFIEDBY - Type is LIST
|MODIFYDATE - Type is LIST .......

I dont see, how this could help me. Thanks again for your help
 
*bonk against my head* okay ListObjects doesnt list all children... it lists all fields from one specific item.

so i have to find out, how i get all DATAIDs which have the same PARENTID.

Is there a way like: select * from DTREE where subtype =144, just using this sql in LAPI ? Something like a Statement using jdbc drivers in Java.
 
Mimetypes are not in the dtree/webnodes record as you want.also lapi is very old type of datastructure programming,OT has discontinued dev and use of it but people like me who did not have the liberty of websvcs still make use of it.

Code:
select dt.name,dv.mimetype from dtree dt,dversdata dv where dv.docid=dt.dataid and dt.dataid=944708

In fact if you search greggriffiths.org I wrote a lapi downloader which uses a jdbc connection may not work now because java has progressed tremendously but I used the relation above to burn a folder full of livelink objects.the file is called Bulk Fetch
you should be able to use purely lapi to get everything you want by recursively going to each container you encounter some clues in this for you
Code:
/*
The code albeit hard coded uses the livelink java api combined
for getting task related info
In this example execute the Live report All late workflows
Written in answer for an functional_nam query in livelink Knowledge Base
tested java version "1.3.1_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_02-b02)
OJVM Client VM (build 9.0.2.572 cdov, Copyright (c) 1998-2002  Oracle Corp., nojit)
@author K N Nair (appoos@hotmail.com) alias appnair/samalayali
kn_nair@ssa-sa.sel.sony.com in tektips
Acknowledgement  for using printTypeTree as a helper function
Fantastic object tree traversal
Glenn Heying (SCorUser8) Department: Sprint Corporate
SPRINT01 Title: Systems Developer V
E-mail: glenn.heying@mail.sprint.com Phone: (816) 665-9626
*/
//package com.nairkn;
import java.util.*;
import com.opentext.api.*;
public class listObjects{
	private static String Server = "localhost"; //livelink host
	private static int Port = 2099; //livelink server port see opentext.ini
	private static String DFT = ""; //default database file or schema
	private static String User = "Admin"; //username
	private static String Pass = "Admin"; //passwd

	public static void main (String [] args)
	{
		try
		{
			//variables
			LLSession session;
                  LAPI_DOCUMENTS doc;//library object
                  LAPI_WORKFLOW flow;//workflow object
                  LLValue value=new LLValue();
		    	  session = new LLSession (Server, Port, DFT, User, Pass);
			      doc = new LAPI_DOCUMENTS (session);
                  flow= new LAPI_WORKFLOW (session);
                  LLValue LLvalueWP=new LLValue();
                  int volID, objID,versionID;
	        if (doc.AccessEnterpriseWS(value) == 0)
		        	{
		              System.out.println("Enterprise accessed");
                      objID = value.toInteger("ID");
                      volID = value.toInteger("VolumeID");
                       System.out.println("Enterprise ID: " + objID);
                       System.out.println("Enterprise Volume: " + volID);

    //PROVIDE a livelink Document with category that one is looking for
      objID=11351;
      LLValue children=new LLValue();
      String viewName = "DTREE";
      String  queryStr="SUBTYPE=144 ";
       if (doc.ListObjects(volID,objID,viewName,queryStr,LAPI_DOCUMENTS.PERM_FULL,children )==0)
       {
	  printTypeTree(children,"|",":");
	  //now after running this if you would just like to enUmerate one RECORD inside that like name
	     System.out.println("I AM IMPATIENT SHOW ME JUST NAME***************");
		printTypeTree(children.toValue("NAME"),"|",":");
		System.out.println("I AM IMPATIENT SHOW ME JUST SUBTYPE***************");
		printTypeTree(children.toValue("SUBTYPE"),"|",":");
		
		//another way bad programming but since we know that all columns of dtree are lists we can do a shortcut
		//if one of the enumerations are not LIST that si when you get unhandled exception errors such as
		//getname not implemented.LAPI will return either success or failure and the return values may 
		//or maynot be enumeratable.In short handle your exceptions at the client yourself.
		System.out.println("I AM IMPATIENT ALL I CARE IS THE NAME RECORD***************");
			for(int i = 0; i < children.toValue("NAME").size(); i++) {
					System.out.print("The name of this object is----"+children.toValue("NAME").toValue(i));
					System.out.print("I THINK ITS SUBTYPE IS--"+children.toValue("SUBTYPE").toValue(i));
					System.out.println("WHEN I AM A CONTAINER SUBTYPE(FOLDER,PROJECT,DISCUSSSION ETC) I SHOULD BE RECURSIVELY CALLED TO GET ITS CONTENTS");
				}
		
	  }
	   else
	  	{
	   				//Error Checking
	   				System.out.println("Failed to execute Document");
	   				System.out.println("Status Code: " + session.getStatus());
	   				System.out.println("Api Error: " + session.getApiError());
	   				System.out.println("Error Message: " + session.getErrMsg());
	   				System.out.println("Status Message: " + session.getStatusMessage());
			}





      }

			else
			{
				//Error Checking
				System.out.println("Failed to execute Document");
				System.out.println("Status Code: " + session.getStatus());
				System.out.println("Api Error: " + session.getApiError());
				System.out.println("Error Message: " + session.getErrMsg());
				System.out.println("Status Message: " + session.getStatusMessage());
			}





















		}
		catch (Throwable e)
		{
			System.err.println(e.getMessage() );
			e.printStackTrace (System.err);
		}
	}



//Helper class which was published by another
//user in the LAPI discussion
private static void printTypeTree(LLValue inVal, String szSep, String szName) {
		System.out.println(szSep + szName + " - " + printLLValueType(inVal.type()) + "\t" + printLLValue(inVal));
		if(inVal.type() == LLValue.LL_ASSOC ||
				inVal.type() == LLValue.LL_RECORD ||
				inVal.type() == LLValue.LL_TABLE) {
			LLNameEnumeration enumValue;
			enumValue = inVal.enumerateNames();
			while(enumValue.hasMoreElements()) {
				String elValue = enumValue.nextElement().toString();
				printTypeTree(inVal.toValue(elValue), "\t" + szSep, elValue);
			}
		}
		else {
			if(inVal.type() == LLValue.LL_LIST) {
				for(int i = 0; i < inVal.size(); i++) {
					printTypeTree(inVal.toValue(i), "\t" + szSep, "" + i);
				}
			}
		}
	}

	private static String printLLValue(LLValue llVal)
	{
		String returnString = "";

		switch (llVal.type()) {
		case LLValue.LL_BOOLEAN :
			returnString = "" + llVal.toBoolean();
			break;
		case LLValue.LL_DATE :
			returnString = llVal.toDate().toString();
			break;
		case LLValue.LL_DOUBLE :
			returnString = "" + llVal.toDouble();
			break;
		case LLValue.LL_INTEGER :
			returnString = "" + llVal.toInteger();
			break;
		case LLValue.LL_STRING :
			returnString = llVal.toString();
			break;
		default :
			break;
		}
		return returnString;
	}

	private static String printLLValueType(int iType) {
		String returnString = " ";
		switch (iType) {
		case LLValue.LL_ASSOC :
			returnString = "Type is ASSOC";
			break;
		case LLValue.LL_BOOLEAN :
			returnString = "Type is BOOLEAN";
			break;
		case LLValue.LL_DATE :
			returnString = "Type is DATE";
			break;
		case LLValue.LL_DOUBLE :
			returnString = "Type is DOUBLE";
			break;
		case LLValue.LL_ERROR :
			returnString = "Type is ERROR";
			break;
		case LLValue.LL_INTEGER :
			returnString = "Type is INTEGER";
			break;
		case LLValue.LL_LIST :
			returnString = "Type is LIST";
			break;
		case LLValue.LL_NOTSET :
			returnString = "Type is NOTSET";
			break;
		case LLValue.LL_RECORD :
			returnString = "Type is RECORD";
			break;
		case LLValue.LL_STRING :
			returnString = "Type is STRING";
			break;
		case LLValue.LL_TABLE :
			returnString = "Type is TABLE";
			break;
		case LLValue.LL_UNDEFINED :
			returnString = "Type is UNDEFINED";
			break;
		default :
			returnString = "Type is Unknown";
			break;
		}
		return returnString;
	}//helper method ends





}//class ends here

Well, if I called the wrong number, why did you answer the phone?
James Thurber, New Yorker cartoon caption, June 5, 1937
Certified OT Developer,Livelink ECM Champion 2008,Livelink ECM Champion 2010
 
BTW see if you can download EasyLapi from the kb all these crazy data structures have been encapsulated into useful calls so it looks more or less like one java call.For e.g there may be a call to give you a recursive listing in one shot

Sorry I should have mentioned that before sending you on raw lapi stuff it might be a whole lot easier and un frustrating

Well, if I called the wrong number, why did you answer the phone?
James Thurber, New Yorker cartoon caption, June 5, 1937
Certified OT Developer,Livelink ECM Champion 2008,Livelink ECM Champion 2010
 
thanks again....

but this also leads me nowhere :D
I AM IMPATIENT SHOW ME JUST NAME***************
|: - Type is LIST
I AM IMPATIENT SHOW ME JUST SUBTYPE***************
|: - Type is LIST
I AM IMPATIENT ALL I CARE IS THE NAME RECORD***************

the children Object contains no Values. I choose a folder which contains two *.msg Files: Parentdir is 2000.

I found a way of getting the information i want:
doc.GetObjectInfo(0, id, dirInfo);

but to use this, i need the DATAID. Is there a way of getting ALL Dataids contaning in the contenServer? I dont see it. ListObjects might no work for that. Or is there a mistake ?
 
RUN your listobjects call without a subtype filter and try to understand what the call is doing
what is your output when you run select * from dtree where parentid=2000 do you see your two msg files in that.If so list objects also is doing that

Is the lapi user connecting a user who cannot see the files permission wise? can you for testing use the livelink user 'Admin'

Here's how livelink uses the ListObjects to show you the hierarchy

2000(Enterprise)
1234(subtype 0 My Folder)
1568 (subtype=144 My Document inside it)
1345(subtype=144 My document)

If you do
ListObjects without a subtype=filter
on 2000 and assuming you have permissions to see all the children it will display
2000
1234
1345

It will not show 1568 because the call will not recurse into 1234.You have to code to do the traversing.

If you do ListObjects on 2000 with subtype=0

1234

If you do ListObjects on 2000 with subtype=144
1345

That is how the oscript code(the lapi converts into oscript) is written,if it is not happening for you you might want to ask OT suppport why it is not working the way it should be.




Well, if I called the wrong number, why did you answer the phone?
James Thurber, New Yorker cartoon caption, June 5, 1937
Certified OT Developer,Livelink ECM Champion 2008,Livelink ECM Champion 2010
 
my layout is:

2000(Enterprise)
14867 ManagePersonalVolumes (subtype=?)
33346(subtype 0 Testfolder)
33237 (subtype=144 Test.msg)
33899(subtype=144 lapi.h file)


the i try this call:
Code:
int volID = 0;
                    int objID = 2000;
                    LLValue children = new LLValue();
                    String viewName = "DTREE";
                    String queryStr = "subtype=144";
                    if (doc.ListObjects(volID, objID, viewName, queryStr, LAPI_DOCUMENTS.PERM_FULL, children) == 0)
                    {
                        printTypeTree(children, "|", ":");
                        //now after running this if you would just like to enUmerate one 
                        //RECORD inside that like name
                        Console.WriteLine("I AM IMPATIENT SHOW ME JUST NAME***************");
                        printTypeTree(children.toValue("NAME"), "|", ":");
                        Console.WriteLine("I AM IMPATIENT SHOW ME JUST SUBTYPE***************");
                        printTypeTree(children.toValue("SUBTYPE"), "|", ":");

                       
                        Console.WriteLine("I AM IMPATIENT ALL I CARE IS THE NAME RECORD***************");
                        for (int i = 0; i < children.toValue("NAME").size(); i++)
                        {
                            Console.Write("The name of this object is----" + children.toValue("NAME").toValue(i));
                            Console.Write("I THINK ITS SUBTYPE IS--" + children.toValue("SUBTYPE").toValue(i));
                            Console.WriteLine("WHEN I AM A CONTAINER SUBTYPE(FOLDER,PROJECT,DISCUSSSION ETC) I SHOULD BE RECURSIVELY CALLED TO GET ITS CONTENTS");


                        }
                    }

i got the following error:

com.opentext.api.LLIllegalOperationException: toInteger() not implemented for th
is datatype
bei com.opentext.api.LLInstance.toInteger()
bei com.opentext.api.LLValue.toInteger()
bei com.opentext.api.LLConnect.unMarshall()
bei com.opentext.api.LLSession.unMarshall()
bei com.opentext.api.LAPI_DOCUMENTS.ListObjects(Int32 VolumeID, Int32 NodeID,
String ViewName, String QueryStr, Int32 Permissions, LLValue children)
bei OpenTextTest.Program.Main(String[] args) in C:\Users\Outlook\Documents\Vi.....

i dont know what is wrong here. If i select 33346 as Objectid, and paste subtype =144 i got the same error, if i put subtype=0 it is working, but only gives empty results like i postet above.
The user i connected with has all viewing rights... he is the owner of the docs.

same tointeger Error occurs, when i use: String queryStr = "";
 
okay .... i solved it !

String viewName = "DTREE"; was the problem

Code:
 parentVol = 0;
                    parentID = 2000;
                    LLValue children = (new LLValue()).setTable();
                    String viewName = null;
                    String queryStr = "subtype=144";
                    status = doc.ListObjects(parentVol, parentID, null, queryStr, 0, children);


i had to set viewName to null.... now i am gettig all the Information i want.... maybe you can explain it to me, why "DTree" is not working, like in all examples i found. Also in the documentation it is mentioned to use Dtree if you want all columns .... i would be happy to get an explanation
 
if viewname is null then webnodes is used listnodes is a call that can be maliciously used.You have to sometimes enable calling tables in livelink.if you search in KB you can get the real scoop on that.You have to do something like whitelisting and blacklisting I cannot determine for sure until I can see debug logs

Well, if I called the wrong number, why did you answer the phone?
James Thurber, New Yorker cartoon caption, June 5, 1937
Certified OT Developer,Livelink ECM Champion 2008,Livelink ECM Champion 2010
 
thanks a lot. you helped me starting in this Lapi stuff....
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top