Remove Unused Variables in CSIDE

A very interesting function is “Remove Unused Variables” in CSIDE:

Where fo find the command
Where fo find the command

This command will remove all unused variables from the functions in the edit window.

The command at work

At left, you see the declaration “integer s=1”, which is not used in the function. At right, you see, this declaration is deleted after the execution of the “Remove Unused Variables” command

Upload a file into the content server from OScript

If you want to upload a file into the content server from your module, you can use something like this

function Assoc UploadFile(Record r, Integer FolderID, String fieldName)
    Dynamic retNodeID = -1 
    DAPINODE docNode 
    // Get the ATTACHMENT_FOLDER node and set some options.
    // ParentID = 2000 (Enterprise) 
    Object prgSession = .PrgSession()
    Object session = prgSession.DSession()
    DAPINODE nodeFolder=    DAPI.GetNodeByID(session.fSession,DAPI.BY_DATAID,FolderID,False )
    // Make the node name from the file and eventID. It has to be unique, so
   // check it, and append a number if necessary.
    String fname=$WebDoc.WebDocUtils.GetFileUploadName(r,fieldName)
    Assoc retUniq
    String sTmp=fname
    Integer cnt=0
    retUniq=$LLIApi.NodeUtil.IsNameUnique(sTmp,nodeFolder)
    while !(retUniq.OK)
       cnt+=1
       sTmp=fname+"_"+Str.ValueToString(cnt)
       retUniq=$LLIApi.NodeUtil.IsNameUnique(sTmp,nodeFolder)
    end
    fname=sTmp
    // Upload the document as a new node.
    Assoc result = $WebDoc.WebDocUtils.CreateFileUploadDocument(nodeFolder,r,fieldName,fname)
    return(result) 
  end

First, the folder ID is used to get the DAPINODE of the parent folder. The node name must be unique, so a check is necessary to ensure, that the intended nodename is not existing.

Then the file is uploaded.

Remark: This function does not consider mandatory categories, which must be added at upload time.

New CSIDE Function Format Source

The new CSIDE function allows a direct format of the OSCRIPT source code inside the IDE.

Imagine this short function in OSCRIPT. This is very unreadable.

By pressing CRTL+SHIFT+F inside the OSCRIPT window, the source code is reformatted automatically and the result looks much more readable:

Building a Content Server Request Handler for AJAX Client Requests

In the standard request handler usage scenarios, there is always a complete URL, which is send to the server. Then the server processes that and returns the result page to the client.

With a little change, these standard request handlers in a module can be modified to be used from clients asynchronously by the usage of AJAX.

Client Part

The easiest approach is to use AJAX with JQUERY (which is delivered by the content server). If the base page was built from another request handler, it can include weblingo constructs. These are OSCRIPT parts, delimited by `-Delimiters. Like JSP, the final renderer evaluates everything between two delimiters and replaces that with the result of the evaluation.

So a AJAX JQUERY command with intermixed OSCRIPT parts can look like that:

This is a simple AJAX call, calling the request handler on the server as usual. But there is a parameter called func, which contains the actual request handler address and one parameter nodeid, which is the data parameter.

Request Handler
AJAX Part

Server Part

A sample request handler looks like this listing below. There is a prototype declared, this prototype must exist in the request.

Server Request Handler
Server Request Handler

The rest of the data is encapsulated in the JSON array. This array can be parsed into an assoc with the call to

$WebLL.JSONUtils.ParseJSON(request.configData)

and processed in the standard way.

Any responses should be handled in the standard way with an assoc.

String tst = $WebLL.JSONUtils.ToJSON(response)
  Web.Write(ctxOut, $WebLL.JSONUtils.GetJSONHeader(.fExtraHeaders))
  Web.Write(ctxOut, tst);
  .fHTMLFile = Undefined

This assoc is changed with a call to the ToJSON to a normal string.

Here, we do not have a output html file, so we have to use a Web.Write to write the output directly to the port. Do not forget to include the JSONHeaders.

The fHTMLFile stores normally the weblingo output file and has to be set to undefined in this case.

package DELIVERER::PUBLICATOR::AJAXHANDLER

public object UpdateAjax inherits DELIVERER::RequestHandlerOrphans::LLRequestHandler

override Boolean fEnabled = TRUE
  override String fFuncPrefix = 'deliverer'
  override Dynamic fHTMLFile
  override List fPrototype = { { 'configdata', -1, 'The config data changed at the client', FALSE } }
  /*
  * This is the Request handler to handle the Ajax Update Request(s)
  * Based on the original Request handlers, this handler receives an AJAX Request from the NodeAction Browse Page
  * and sends the Response back to the Browse Page (PUBLICATOR.html)
  *
  * @param {Dynamic} ctxIn
  * @param {Dynamic} ctxOut
  * @param {Record} request
  *
  * @return {Dynamic} Undefined
  */
  override function Dynamic Execute( \
  Dynamic ctxIn, \
  Dynamic ctxOut, \
  Record request )

Object prgCtx = .PrgSession()
  Assoc response = Assoc.CreateAssoc()
  Assoc cDat = $WebLL.JSONUtils.ParseJSON(request.configData)
  integer nodeid = cDat.id
  DAPINode node = DAPI.GetNodeByID(prgCtx.DapiSess(),nodeid)
  Assoc.Delete(cDat,"id") // remove the NodeID
  string remark = cDat.remark
  Assoc.Delete(cDat,"remark");
  node.pComment=remark
  // save configdata in pExtendedData
  // do not forget to include other assocs, if needed from the pExtendedData
  Assoc a = node.pExtendedData;
  //TODO Add Things
  a.configdata=cDat
  node.pExtendedData = a

DAPI.UpdateNode(node) // store it

// Send response
  response.ok="OK"
  response.msg="Fine"
  String tst = $WebLL.JSONUtils.ToJSON(response)
  Web.Write(ctxOut, $WebLL.JSONUtils.GetJSONHeader(.fExtraHeaders))
  Web.Write(ctxOut, tst);
  .fHTMLFile = Undefined

return Undefined
  end

end

Authentication (3/3) Authenticate with Webservices and Java against Content Server

To authenticate with a JAVA client against a Content Server, you should first create all client proxys. This example can be used against a Servlet Container, like Tomcat. Here, it is assumed, that it runs on port 8080.

The creation of the proxys must be done manually by typing

wsimport -keep http://yourserver:8080/cws/services/Authentication?wsdl
 [add all services you want to use]

jar cvfM webservices.jar com/opentext/*

Add the webservices.jar file in the build path of your Java application.

Then, use something like this to authenticate

String username = "[yourUser]";
  String passsword = "[yourpassword]";
  Authentication_Service authsrv = new Authentication_Service();
  Authentication authclient = authsrv.getbasicHttpBindingAuthentication();
  // the Token
  String authToken=null;
  // authenticate
  try
  {
      authToken = authclient.authenticateUser(username,password);
  } catch (SOAPFaultException e)
  {
      System.out.println("Failed! "+e.getFault().e.getFaultCode()+" : "+e.getMessage());
  }

This will, if succesful, store the authenticaten token in the string authToken.

Use this token in this way:

DocumentManagement_Service docmanSrv = new DocumentManagement_Service();

DocumentManagement docman = docmanSrv.getbasicHttpDocumentManagement();

OTAuthentication otAuth = new OTAuthentication();

otAuth.setAuthenticationToken(authToken);

Now, we have to set the token manually in the SOAP header

try

{

    final String API_NAMESPACE = "urn:api.ecm.opentext.com";
     SOAPHeader header = MessageFactory.newInstance().createMessage().getSOAPPart().getEnvelope().getHeader();
     SOAPHeaderElement authElement = header.addHeaderElement (new QName(API_NAMESPACE,"OPAuthentication"));
     SOAPElement authTokenElement = authElement.addChildElement (new QName(API_NAMESPACE, "AuthenticationToken"));
     authTokenElement.addTextNode (otAuth.getAuthenticationToken());
     ((WSBindingProvider) docMan).setOutboundHeaders (Headers.create(otAuthElement));
  } catch (SOAPExeption e)

{

[Print Error and return]

}

// now, we are ready to perform some functionality

Node node = docman.getNode(nodeId);
  1. Login and get the auth token
  2. set the auth token in the SOAP header
  3. tell your services about the auth token in the SOAP header
  4. perform operations on the server

Do not forget to refresh the token before it gets invalid. We discuss the refesh in a later posting.

Authentication (2/3) Authenticate with Webservices against the Content Server in c#

This is the second post on a series about authentication against the content server. This post explains the authentication from a c# application using Webservices.

Normally, the Webservices are used from a Java application container like Tomcat. To use this snippet, a Service Reference exist inside Visual Studio with the URL

http://[yourServer]:8080/cws/services/Authentication?wsdl

with the name of “Authentication”.

The Authentication itself is done with something like this:

Authentication.AuthenticationClient authClient = new Authentication.AuthenticationClient();

string authToken = null;
try
{
     Console.Write(“Authenticate User…”);
     authToken = authClient.AuthenticateUser(userId, password);
     Console.WriteLine(“Success \n”);
} catch (Exception e) {
     Console.WriteLine(“failed\n”);
     Console.WriteLine(“{0} : {1} \n”, e.Message, e.Source);
     return;
}
finally
{
     authClient.Close();
}

Here, the userid and the password is send to the Authentication service. If all is correct, the authentication token is send back.

This token can be used like in the following snippet. Here, the Node 485227 is requested.

DocumentManagement.DocumentManagementClient docclient = new    DocumentManagement.DocumentManagementClient();
DocumentManagement.OTAuthentication otauth = new    DocumentManagement.OTAuthentication();
otauth.AuthenticationToken = authToken;

// Get the Node 485227 
DocumentManagement.Node node = docclient.GetNode(ref otauth, 485227);

Like the Authentification Service, the DocumentManagement Service must be declared as a Service Reference in Visual Studio. When a Tomcat is used, then the declaration looks like

http://[yourServer]:8080/cws/services/DocumentManagement?wsdl

To use the token, declare an instance of Documentmanagement.OTAuthentication and put the token in the AuthenticationToken field of this instance.

Then use the webservices calls as usual, but add the instance of this OTAuthentication as a reference in the first argument of the call.

Tipp: save this instance as a copy, from time to time the first argument returns as null. Then you can re-instate the original OTAuthentication.

If you want to use Webservices in IIS, pls refer to the post from January 2017.

Authentication (1/3) How to authenticate against the Content Server in REST/Javascript

This is the first post on a series about authentication against the content server. The first post explains the authentication from a html page with Javascript and JQuery using REST

The REST API can be used to perfom things on the Content Server from nearly every thinkable language. Here is the example how to do a login from Javascript.

Replace [yourserver] with the DNS name of your Content Server, replace [yourCSInstance] with your CS instance and the cgi.

A valid URL would be for example

http://AllmyServer.mydomain.com/cs16/cs.exe/api/v1/auth

for the Authentication request.

<script>
  var otcsticket = "";
  /*
  * This function needs to be run first to authenticate the user against Content Server.
  */
  function authenticate() {
  // Set up the ajax request
  $.ajax({
  // Authenticate is a POST
  type: "POST",
  url: "http://[yourserver]/[yourCSInstance]/api/v1/auth",
  data: { username: [username], password: [password] },
  beforeSend: function( xhr ) {
  // Set the correct MimeType for the request.
  xhr.overrideMimeType( "application/x-www-form-urlencoded" )
  }
  }).done( function( data ) {

var val = JSON.parse( data );
  alert( "setting otcsticket to: " + val[ "ticket" ] );
  // Store the ticket for later use.
  otcsticket = val[ "ticket" ];

});
  }
 </script>

To authenticate, a $.ajax call is used. The REST call to do this is “/api/v1/auth”. The data must contain a valid username and a valid password for this user.

If the call is finished, then the JSON array (in the response) must be parsed for the key “ticket”. The value is the authentication token which should be stored somewhere for further use. Normally, the name otcsticket is used for this.

The token should be send as a header in any request, like in this example:

$.ajax( {
  type: "POST",
  url: "[yourURL]/api/v1/nodes",
  data: bodyData,
  headers: { otcsticket: otcsticket },
  beforeSend: function( xhr ) {
  // Set the correct MimeType for the request.
  xhr.overrideMimeType( "application/x-www-form-urlencoded" )
  }
  } ).then( function ( response ) {
  alert("Success")
  }, function ( jqxhr ) {
  alert("failure")
  } );

(This is a call to upload a file, for the complete example on uploading files with REST see the posts in January 2017)