Hi!

Featured

My name is Ramindu Deshapriya. By profession, I’m a Software Engineer. I revel in being a diverse programmer and have worked with PHP, C, Java, Android, MySQL, SAP ABAP and quite a few others. The world is full of knowledge, and there’s so much more to learn!
I’m an open-source enthusiast. I’ve worked on the Bug Squad for the Joomla! project, and am currently involved in development of Sahana Vesuvius for the Sahana Software Foundation. I also work as the Assitant Editor for the Free and Open Source Software User Magazine of Sri Lanka.
In my spare time I play rhythm guitar for Dhishti. I also love reading, computer gaming, watching movies, and swimming.
To me, life, with all its ups and downs, is worth all the bad times as well as the good, and I would not change a single aspect of my personal history even if given the chance to do so.

Adding the AndEngine Box2D Physics Extension to an AndEngine project

I’ve talked about AndEngine before as a great framework for building 2D games on the Android platform. Today, I will be explaining how to include the AndEngine Box2D extension within an AndEngine project so that you can start implementing realistic physics within your game.

The AndEnginePhysicsBox2DExtension, provides an implementation of the popular C++ Box2D physics framework for AndEngine. Getting this doohicky integrated with your current AndEngine project can be a little tricky, however, and that’s what I’m going to explain today.

First, you need to have an Eclipse project with AndEngine included in any way you prefer. Note that you’ll have to have AndEngine as a library project in Eclipse before you begin, as the Box2D Extension will need it as well.

The next step is to clone the Github repository for the AndEnginePhysicsBox2DExtension.

Git Clone the Box2D Extension

Git Clone the Box2D Extension

Now, import the extension as a Library project to your Eclipse workspace. (Right click on workspace -> Import -> Android -> Android Project from Existing Code).

Import the extension as existing Android code to your workspace

Import the extension as existing Android code to your workspace

Once you’ve imported the extension, it will immediately build a set of JARs and various other binary files. Now, there are two ways to include the extension in to an existing AndEngine project:

  1. Include it as a library project (recommended) :
    1. Make sure your AndEnginePhysicsBox2DExtension workspace project is pegged as a library. You should be be able to check this by right clicking on the extension project, going to properties, and checking whether ‘Is Library’ is ticked under the Android section.
      Make sure that your extension project is a library

      Make sure that your extension project is a library

      Now, right click on your existing AndEngine project and go to Properties and go to the Android Section. In the libraries box at the bottom, you should be able to add the AndEnginePhysicsBox2DExtension as a library.

      Add the extension as a library to your AndEngine project

      Add the extension as a library to your AndEngine project

  2. Add AndEnginePhysicsBox2DExtension binaries to your libs folder:
    1. As I mentioned earlier, your AndEnginePhysicsBox2DExtension workspace project will build a set of extension binaries in the /bin folder as soon as you import it. Although it is not recommended by the developer of AndEngine, you can copy over these files to your AndEngine project’s /libs folder.
      Copy Physics Extension JAR files to your /libs folder

      Copy Physics Extension JAR files to your /libs folder

       

Now that you’ve included the AndEnginePhysicsBox2DExtension within your AndEngine project, you can proceed to write awesome physics code in to your game, like including the gravity of the first Death Star within the game’s environment!

Use the gravity of the first Death Star in your game! This is actually an Android thing, not an AndEngine thing.

Use the gravity of the first Death Star in your game! This is actually an Android thing, not an AndEngine thing.

Building and sending a SOAP Envelope via Axis2 Client

The Apache Axis2 library is one of the world’s most renowned FOSS solutions for writing and deploying web services. This library ties in very closely with the Apache Axiom library which is used to build the Object Model needed to send and receive SOAP messages for web services built using Axis2.

Today we’re going to take a look at how to build a SOAP envelope from a String value and how to set it to an Axis2 service client message context. There are a few things we need to do in order to accomplish this:

  1. Create a ServiceClient object.
  2. Create an Options object and set the endpoint URL for the service we’re going to call.
  3. Create a new MessageContext object.
  4. Create a SOAPEnvelope object from a given string using Axis2 TransportUtils.
  5. Set the SOAP envelope object to the MessageContext object.
  6. Use the ServiceClient object’s createClient method to generate an OperationClient object for this operation.
  7. Add the MessageContext object to the OperationClient object.
  8. Execute the OperationClient object.

Code:

final String MY_OM_STRING = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
                        + "   <soapenv:Header/>\n"
                        + "   <soapenv:Body>\n"
                        + "     <my_xml_tag>My Value</my_xml_tag>\n"
                        + "   </soapenv:Body>\n"
                        + "  </soapenv:Envelope>";
//1. Create new ServiceClient object
ServiceClient serviceClient = new ServiceClient();

//2. Create an Options object and set the endpoint URL for the service we're going to call
Options serviceOptions = new Options();
serviceOptions.setTo(new EndpointReference(ENDPOINT_URL);
serviceClient.setOptions(serviceOptions);

//3. Create a new MessageContext object
MessageContext messageContext = new MessageContext();

//4. Create a SOAPEnvelope object from a given string
OMElement myOMElement = AXIOMUtil.stringToOM(MY_OM_STRING);
SOAPEnvelope soapEnvelope = TransportUtils.createSOAPEnvelope(myOMElement);

//5. Set the SOAP envelope object to the MessageContext object
messageContext.setEnvelope(soapEnvelope);

//6. Use the ServiceClient object's createClient method to generate an OperationClient
OperationClient opClient = serviceClient.createClient(ServiceClient.ANON_OUT_IN_OP);

//7. Add the MessageContext object to the OperationClient object
opClient.addMessageContext(messageContext);

//8. Execute the OperationClient object
opClient.execute(true);

And that’s how its done.

Configuring and carrying out a FULLTEXT search in MySQL

When we normally have an application associated with a MySQL database and we want to carry out a search, we would normally go for the yucky “LIKE%” syntax when writing our search query. What if I told you that there is a much better indexed method built right in to MySQL that you could use to run an optimised and effective search? Welcome to the world of MySQL Fulltext searching. Today we’ll discuss how to define Fulltext indices on a MySQL database table and how to run a simple search query on them.

First things first, let’s install PhpMyAdmin. I’m going to assume that you already have MySQL installed. PhpMyAdmin is a handy tool that lets us manage our MySQL databases without having to go through the hassle of typing out long terminal commands. You can use any other similar GUI tool such as MySQL Workbench as well.

Now, I have a database called etutor where I have a table called questions. In order to set up Fulltext indices on this table, I’m going to have to convert it to a MyISAM-engine-based table. This can be achieved by selecting the table and going to the ‘Operations’ tab:

You can set a table's engine to MyISAM by going to the 'Operations' tab

You can set a table’s engine to MyISAM by going to the ‘Operations’ tab

When I open up the structure of the questions table in PhpMyAdmin, there’s a small ‘fulltext’ icon on the right of each attribute of the table.

The Fulltext button can be seen next to each column name

The Fulltext button can be seen next to each column name

This is the button with the little ‘T’ on it. Clicking on this will define that attribute (it needs to be VARCHAR or Text) type as a Fulltext index, which we can search on.

Expanding the ‘Details’ section at the bottom of the page will show you all the Fulltext indices you’ve defined on your table.

The Fulltext index list can be seen at the bottom of the page

The Fulltext index list can be seen at the bottom of the page

Its that simple to define a Fulltext index on your database table! Now let’s move on to some searching.

My search query will utilise the ‘MATCH’ and ‘AGAINST’ keywords in MySQL to search through my Fulltext indices:

SELECT * FROM questions WHERE MATCH(subject)
AGAINST('SEARCH_QUERY') OR MATCH(tags)
AGAINST('SEARCH_QUERY');

And frankly, it’s that simple to search through those pesky text indices too. You will find that there is a massive performance boost when using Fulltext search vs. the traditional ‘LIKE%’ query approach.

Some Physics functions in AndEngine GLES1.0 + Box2D

AndEngine is one of the best game engines available to build 2D games on the Android platform. It has a load of great features, one of which its integration with the Box2D physics engine. This is done via a great extension.

There are many sources out there to help developers with integrating physics features in to AndEngine, including examples from the author of the engine himself, however, I thought of writing my own helpful guide with some of the lesser-explained functions of AndEngine’s physics engine.

You’ll be able to use this awesome blog post by Maya Posch to set up AndEngine and get it configured with the AndEngine Physics Box2D Extension. It’s a bit complicated, so if you’re lazy like me you could find the compiled sources from the previously-linked Examples repository (though this is NOT recommended).

Now, to get started on some of the functions that you’ll need. The Box2D environment, when oversimplified, contains the following main elements:

  • Physics World: This is where all the exciting business goes on, and where all the elements related to physics are stored and manipulated. Welcome to the world of physics!
  • Bodies: Bodies are similar to sprites in any game; they’re what move about, crash in to each other etc.
  • Vectors: These are what you’ll be applying on your bodies (you do know your basic physics, right?) to make them move around, rotate, stop, and every other conceivable thing.

Basics aside, we’ll look at a few functionalities that are rarely explained in most AndEngine physics examples:

  1. Contact Listeners:

Contact listeners are Box2D’s equivalent to collision detection in game engines. A ContactListener is defined for the Physics World in general, and will handle all contacts that happens in that world. That means, when a contact listener fires, you’ll only get the Fixtures (and underlying Bodies) of that particular contact to manipulate. Handling contact listeners in this way can get pretty dirty pretty fast, it turns in to a mess of checking fixtures for their underlying attributes and rechecking to see if they’re the actual body within the physics world that you want to check for collisions. Well, you did want to have smooth physics in your game, right? Now pay the price. ;)

Following is a code snippet from a car racing game I worked on:

mPhysicsWorld.setContactListener(new ContactListener() {

			public void preSolve(Contact contact, Manifold oldManifold) {

			}

			public void postSolve(Contact contact, ContactImpulse impulse) {

			}

			public void endContact(Contact contact) {

			}

			public void beginContact(Contact contact) {

				if ( contact.getFixtureA().getBody().getUserData() != null &&
						contact.getFixtureB().getBody().getUserData() != null  ) {
                                        //I stored a 'Car' object in the userdata of each physics body as I created it
					final Car carA = (Car)contact.getFixtureA().getBody().getUserData();
					final Car carB = (Car)contact.getFixtureB().getBody().getUserData();
					if ( carA.getId() == 1 || carB.getId() == 1 ) {
						carState = CAR_STATE_CRASHED;
						vibrator.vibrate(100);
                                        }
                                }
                      }
});

By returning the bodies associated with each fixture in teh contact, I have managed to get the ‘Car’ type objects stored within the userdata elements within each body. By checking a specific value within these car objects, I have decided what to do next. Any contact handling that you’d do with AndEngine + Box2D would have to be a lot of if-else clauses where you check whether the bodies crashing together within the physics world are the bodies you want to check for collisions with. The presolve() an postsolve() methods are concerned with preparing the physics world for the contact, where you can set various attributes like whether contacts are enabled at that point.

2. Setting your body’s velocity to 0:

This might seem like a weird requirement, but believe me, after your sprites start bouncing around the screen like crazy ping pong balls, you’ll thank me. This is something it took me a while to figure out, so I thought I’d share:

Vector2 linearZero = Vector2Pool.obtain(0,0);
playerBody.setLinearVelocity(linearZero);
Vector2Pool.recycle(linearZero);//don't forget to recycle your vectors! It helps save the environment.

Ok, so you have your playerBody right? What you do is, you initialize a vector with 0 values, and you apply that as the linear velocity to your body. That will stop the body from moving on all plains.

3. Insta-move your sprite to any place on the screen:

Sometimes, even when you have a physics engine at your disposal, you just want to magically materialize your sprite somewhere on the screen. The problem is, if you use the normal AndEngine sprite.setPosition() method, the physics body you’ve attached to the sprite is not going to move with it. You need to use Box2D itself to insta-move your sprite (once you move the body, the sprite will always move with it, but not vice-versa):

 

Vector2 transformVector = Vector2Pool.obtain(newXPosition, newYPosition);
playerBody.setTransform(transformVector, playerBody.getAngle());
Vector2Pool.recycle(transformVector);

Vectors again. Simply build a new vector containing the X and Y coordinates you want to move your sprite to, and use the setTransform() method on the body attached to the sprite.

 

That’s it from me for now. More soon!

Handling HTTP Digest Authentication using Ruby

You may have encountered an authentication-required header when making HTTP requests to various web services or websites. While the basic authentication scheme for HTTP simply requires you to submit username and password details for that particular URL, there are other protocols which enhance the level of security that can be applied to an HTTP connection. HTTP Digest Authentication, which has been specified by this RFC, is one such method than can be used to provide enhanced security for HTTP-based web service connections.

HTTP Digest Authentication is based primarily on two concepts; MD5 hashing and dynamically-generated nonce values. The nonce values are used to ensure that a particular call to the server is part of an ongoing conversation between that particular client and the server, without anyone else (hackers ;) ) butting in.

To call a web service employing HTTP Digest authentication, you must first send an empty request to the server which will return a server-generated nonce value for you. Then you can proceed to the next steps in authentication, which involves hashing your username and password with the nonce in the middle, as well as setting various header values.

Recently, I implemented some Ruby code to call a web service using HTTP Digest authentication, and I thought of sharing my code. I based most of it on the HTTP Digest Auth Ruby Gem.

Here’s the code:

# Build header authorization block to send to given URI
    def build_header_auth(uri, version, httpmethod) response = get_auth_response(uri)
	    @cnonce = Digest::MD5.hexdigest("%x" % (Time.now.to_i + rand(65535)))
        @@nonce_count += 1 response['www-authenticate'] =~ /^(\w+) (.*)/
        challenge = $2
        params = {}
        challenge.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 }

        a_1 = "#{@username}:#{params['realm']}:#{@password}" #username, realm and password
        a_2 = "#{httpmethod}:#{uri}" #method and path
        request_digest = '' request_digest &lt;&lt; Digest::MD5.hexdigest(a_1)
        request_digest << ':' << params['nonce']
        request_digest << ':' << ('%08x' % @@nonce_count)
        request_digest << ':' << @cnonce
        request_digest << ':' << params['qop']
        request_digest << ':' << Digest::MD5.hexdigest(a_2)

        header = []
        header << "Digest username=\"#{@username}\""
        header << "realm=\"#{params['realm']}\""
        header << "qop=#{params['qop']}"
        header << "algorithm=MD5"
        header << "uri=\"#{uri}\""
        header << "nonce=\"#{params['nonce']}\""
        header << "nc=#{'%08x' % @@nonce_count}"
        header << "cnonce=\"#{@cnonce}\""
        header << "response=\"#{Digest::MD5.hexdigest(request_digest)}\""
        header << "opaque=\"#{params['opaque']}\""
        header_auth_str = header.join(', ')

# Build request (allows reuse)
    def build_request()
        @http = Net::HTTP.new(@uri.host, @uri.port)
        @http.use_ssl = true
        @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
    end

# We need to get a response with a WWW-Authenticate request header
    def get_auth_response(uri)
        url = BASE_URL + uri
        @uri = URI.parse(url)
        build_request()
        req = Net::HTTP::Get.new(@uri.request_uri)
        response = @http.request(req)
        return response
    end

Good Luck!

Android – Figuring out the Mobile Network programmatically

On building an Android app for a specific mobile operator, I was once faced with the problem of making sure the phone running the app would have a SIM connected to that particular operator. Since the app I built functions completely independently from the mobile operator, I needed to figure out a solution to stop users on other networks from using it to ensure exclusivity for my client.

The obvious solution to this (at least, the solution which I thought of first) is to check the SIM’s mobile number, do some parsing and then figure out which operator the SIM is on. However, turns out nowadays the mobile phone number is not stored on the SIM card like it was in the old days. It is assigned dynamically by the mobile service provider, and this is why when you lose your SIM card you can simply get a new one with the old number assigned to it.

The method I used to get this done is using the checking the Mobile Country Code (MCC) + Mobile Network Code (MNC) combination that can be gained through a call to the TelephonyManager class’s getSimOperator method.

Code is as follows:

import android.telephony.TelephonyManager;
  TelephonyManager tMgr =  (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
  String operator = tMgr.getSimOperator(); // this returns the MCC+MNC
/* Do whatever checks you need here */

The above code will return the MCC + MNC composite for you. For Sri Lanka, the MCC is 413 and the MNCs are as follows:

  • Mobitel – 01
  • Dialog – 02
  • Etisalat – 03
  • Airtel – 05
  • Hutch – 08

For more information on MCCs and MNCs, you can go to the Wikipedia article.

Connecting SAP and PHP

SAP is said to be the most comprehensive and widely-used Enterprise Resource Planning system ever. Due to its widespread use, SAP users and developers come across a variety of situations where they need to connect an installation of SAP to a different platform/programming language so that the data and data interpretations contained in relation to that installation can be accessed by that platform or programming language. Hence a myriad of SAP connectors for different programming languages have been born.

PHP, being the most widely used server-side programming language on the web, is one of the most probable languages that would need to connect to SAP at some point or the other. For this, the extremely handy SAPRFC module for PHP has been developed. This post will discuss an end-to-end implementation of the SAPRFC PHP module and explain how to connect SAP to the module as well.

The first step is to go to the above link and download the complete saprfc package. The easiest way to interface saprfc with PHP and to get it to work is to download XAMPP 1.7.1 (NOT the latest version). This contains PHP 5.28 which seems to be the only PHP version which works correctly with the SAPRFC module.

Unzip XAMPP and copy php_saprfc_528.dll from your saprfc/ext folder over to the /php/ext/ folder in your XAMPP directory. Locate the php.ini file in XAMPP and open it for editing. Here you will have to find the extensions section and add the line

extension=php_saprfc_528.dll

to this section. Now open the XAMPP Control Panel and start Apache. If you followed the above steps correctly, Apache should start now without any problems. IF it gives an error, go over the above steps again.

First of all, we’ll see what we need to do on the SAP side to expose a Remote Function Module which can be accessed via RFC. All you need to do is to create a ‘remote-enabled’ Function Module in SAP. This can be done by ticking ‘Remote-enabled module’ under the function module’s attributes, as shown below:

SAP RFC

You can write whatever program logic in ABAP in the Function Module. Pay special attention to the Importing and Exporting parameters of the Function Module as these will be what are passed to and from your PHP program.

Next, you need to copy over the saprfc.php library file over from the saprfc module folder to your PHP project directory. You can use the functions contained in this file to create a saprfc object which can login to SAP and access your remote-enabled Function Module.

The following code is essential for your PHP program to access SAP:

require_once('saprfc.php');
$submitted = $_GET['submitted'];
/**
 * Login to SAP system
 * @param String $user
 * @param String $pwd
 */
function login($user, $pwd) {
	//Create SAPRFC instance
	$sap = new saprfc(array(
			"logindata" =>; array(
			      "ASHOST"	=>; "HOSTNAME",
			      "SYSNR"	=>; "SYSTEM NUMBER",
			      "CLIENT"	=>; "CLIENT NUMBEr",
		              "USER"	=>; "USERNAME",
			      "PASSWD"	=>; "PASSWORD"
					),
			"show_errors"=>;true,
			"debug"	     =>;false));

	return $sap;
}
function logoff($sap) {
	$sap->;logoff();
}
/**
 * Function to call SAP RFC
 * @param saprfc $sap
 */
function callRFC($sap, $params) {
	$cust_params = $params['cust_params'];
	$task_params = $params['task_params'];
	$proj_params = $params['proj_params'];
	$result = $sap->;callFunction("ZGRAPH_TOTALDAYS_RFC",
             array(
                   array("IMPORT","CUST_PARAMS",$cust_params),
                   array("IMPORT","TASK_PARAMS",$task_params),
                   array("IMPORT","PROJ_PARAMS",$proj_params),
                   array("EXPORT","CATEGORIES",array()),
                   array("EXPORT","DATA_ACTUAL",array()),
                   array("EXPORT","DATA_ESTIMATE",array())
				       )
					);
	return $result;
}

Note the callRFC function: Importing parameters on the SAP RFC are passed to the $sap->callFunction function as “IMPORT” and Exporting parameters are defined as “EXPORT”. By leaving the “debug” value as ‘true’ on the login function, it is possible to get debug output for each SAP RFC call, as seen here:

SAP PHP debug output

Now you’re ready to go out in to the world with your own PHP program that connects to SAP! Good Luck!

Here’s a final look at what my program looks like. It connects to SAP to pull out project data for reporting using the JavaScript HighCharts library:

tumblr_3

Use of EDXL protocol suite in Sahana implementations

Sahana at the Haiti Earthquake

Sahana at the Haiti Earthquake

Sahana is considered to be the premier Disaster Management System available in the world today. It jump-started the Humanitarian Free and Open Source Software (HFOSS) movement, and has been implemented in various disaster situations around the world.

The Emergencey Data eXchange Language (EDXL) protocol suite is a set of protocols defined by the Organization for the Advancement of Structured Information Standards (OASIS) for communication between various organizations responding to a disaster/emergency situation. As a standard, EDXL allows disaster management software and personnel affiliated with different protocols to communicate with each other on a common platform. Therefore it is essential for the usability of any international disaster management system be compliant with EDXL, and Sahana is no exception.

I have taken the time to document some instances which prove Sahana’s extensive compliance with the EDXL protocol suite.

In 2010, a magnitude 7 earthquake struck the Caribbean nation of Haiti, in the city of Port-au-Prince. Tens of thousands of civilians were killed instantly, while thousands more were trapped beneath rubble, as well as leaving millions of civilians homeless.

During the Sahana Software Foundation’s response to the Haiti Earthquake[6], it deployed the Sahana Haiti 2010 Earthquake Disaster Response Portal – a live and active website hosted at http://haiti.sahanafoundation.org, which provided the following features for the use of disaster responders:

•Organization Registry: This was considered as Phase 1 of the implementation of Sahana. The Organization Registry was used to track the information and activities of the organizations involved in the disaster relief effort, as well as what assets and resources they had available to them. This module made use of the RM and CAP protocols from the EDXL protocol suite.

• Food Cluster Food Request Portal : Designed in order to collaborate with the World Food Program (WFP)’s efforts to distribute food properly among the victims of the disaster. It was used to note the availability of food resources as well as the distribution of these resources. This module made use of the RM protocol of the EDXL protocol suite. An SMS-based notification tool developed for this module is planned to be used as a component of the World Food Programme’s future systems.

• Hospital Management System (HMS) : This module was used to track the details of the hospitals available for the disaster relief efforts in Haiti, as well as other medical institutions. The EDXL-HAVE (Hospital AVailability Exchange) protocol was utilized to transmit data about hospitals in operations related to this module. Various instances of the Hospital Management System were able to transmit data between one another using HAVE successfully.

• Persons Registry : This is one of the main components of Sahana (Vesuvius) which was also implemented to search for missing victims of the Haiti Earthquake. This module was used to register the victims of the Earthquake who were missing and to track them via a collaborative method, by providing access to the system online. In order to store and transmit people data, this system made use of the CAP protocol from the EDXL Suite.

• Disaster Victim Identification Registry (DVI) : This registry was used as a module in the Haiti Disaster relief effort to identify and store the details of verified victims of the disaster. CAP (Common Access Protocol) of the EDXL protocol suite was used in this module.

• Shelter Registry : EDXL-RM was used in this module along with CAP to enable the reporting of the status of shelters available for victims of the Haiti Earthquake. By having an extensive methodology available to track the shelters available, the disaster relief workers were able to assign displaced victims to shelters effectively.

Out of the EDXL family, EDXL-HAVE was extensively used along with Person Finder Interchange Format (PFIF). EDXL-HAVE proved effective in the Hospital Management System and the Disaster Victim Identification Registry. This proved to be the ideal protocol needed to handle the immense amounts of data that needed to be exchanged in order to coordinate the Hospital Management effort.

Sources:

  • Prustalis, M., Bodduluri, P., de Silva, C., Bitner, D., Boon, F., König, D., Treadgold, G. (2010), The Sahana Software Foundation response to the 2010 Haiti Earthquake: A New Standard for Free and Open Source Disaster Data Management Systems
  • Rencoret, N., Stoddard, A., Haver, K., Taylor, G., Harvery, P. (2010), Haiti Earthquake Response – Context Analysis
  • Sahana Software Foundation official web page – http://www.sahanafoundation.org

Misadventures of a SAP n00b

SAP is considered to be the best Enterprise Resource Planning system in the world today, and there are thousands of SAP implementations in many mega-corporations around the world.

I had the opportunity to mess around (at a very beginner level) with ABAP and some Z Programs on the SD and MM modules, and would like to document some of the things I learnt. Especially after reading an awesome SAP blog by my friend Jeewana Premarathne at http://implementsap.blogspot.com, I thought of documenting my (rather minimal) knowledge as an ABAP programmer on my blog as well.

1. Search keyword chaining

Just like with any other keyword, it is possible to chain the search keyword as well to search for multiple strings at the same time. If any of the search strings are found within the target string, sy-subrc will be set to 0.

e.g.

SEARCH target_string FOR:
  'Search string 1',
  'Search string 2'.
IF sy-subrc = 0.
  "Do something if search string is found

2.  Some useful naming conventions: http://bit.ly/yoZGGp

3.   Function to give the user a dropdown list to choose a file from the server to save to

CALL FUNCTION '/SAPDMC/LSM_F4_SERVER_FILE'
EXPORTING
  directory = 'directory on server'
  filemask = ' '
IMPORTING
  serverfile = "return variable name
EXCEPTIONS
  canceled_by_user = 1
OTHERS = 2.

IF sy-subrc <> 0.
  MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
  WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.

The above code will give the user a dropdown list to choose a file from. You can use this file as a variable within the program to write data to or read from. If the file is not available on the server or the directory path you provided is not available, this will result in a dump, so this should be handled accordingly.

4. Using OPEN DATASET to write to a file

Once you have obtained the path to the file, you can use the OPEN DATASET keyword to open this file for writing, and simply write a character string or an internal table to it.

"Open file for writing
OPEN DATASET output_file FOR OUTPUT IN TEXT MODE.

  IF sy-subrc = 0.
    * Write output string to file.
    TRANSFER t_output TO output_file.
  ELSE.
    WRITE 'The file could not be written.'.
  ENDIF.
CLOSE DATASET output_file.

5.   Concatenating char/string type variables

For this, it is possible to use the CONCATENATE keyword. If you want to separate the strings using a delimiter, this can be arranged by adding the SEPARATED BY keyword.

CONCATENATE
  lv_string1,
  lv_string2,
INTO lv_final_string SEPARATED BY 'delimiter'.

That’s about it for now from me. Since I’m such a newbie to this, there may be some mistakes. It should also be noted that SAP ABAP programming is not simply about learning the code and programming away like in other programming languages, but you have to have a thorough understanding of the business involved, as well as its processes. More on that later.