Thursday, December 11, 2014

C++ Necessary to Call Base Destructor?

The answer is no, it is automatically called, but it is also somehow important that the destructor is virtual if the class will be inherited.

Reference: http://stackoverflow.com/questions/677620/do-i-need-to-explicitly-call-the-base-virtual-destructor

Cocos2D-X: Convert String to Integer and Testing For Numeric Value

These can be done quite simply by converting the String to a Cocos2D-X String object and then calling the "intValue()" function on the String. If it is a numeric value, the function will return the value which you can use, or if it is not a numeric value, it will return 0 so it also serves for a test for numeric value, unless of course the value is "0" and you should test for that first.

int val;
String* str = String::create(“123”);
// test for 0
if(str->compare(“0”) == 0){
   val = 0;
}
else {
   val = str->intValue();
   if(val == 0){
       // String is not numeric, handle the error here
   }
   else{
       // String is numeric and its value is saved in the “val” variable
   }
}

Wednesday, December 10, 2014

Cocos2D-X: EventListenerTouchOneByOne no viable overloaded '='

In Cocos2D-X version 3.0 and newer, there is a new way of handling touches (see example code below).

However the first time I used this, I encountered a compile error with message "EventListenerTouchOneByOne no viable overloaded '='" in lines 4-6 below. When this compile error happens, one reason is because of a wrong return type on their callbacks.
   EventListenerTouchOneByOne* touchListener = EventListenerTouchOneByOne::create();
   touchListener->setSwallowTouches(true);
   touchListener->onTouchBegan = CC_CALLBACK_2(MyLayer::touchBegan,this);
   touchListener->onTouchEnded = CC_CALLBACK_2(MyLayer::touchEnded,this);
   touchListener->onTouchCancelled = CC_CALLBACK_2(MyLayer::touchCancelled,this);
   touchListener->onTouchMoved = CC_CALLBACK_2(MyLayer::touchMoved,this);

   _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);

The "onTouchBegan" callback has return type "bool". The rest need to have return type "void". Otherwise you will get the compile error above (I had all of them with return type "bool").
bool MyLayer::touchBegan(Touch *touch, Event *event) {
return true;
}
void MyLayer::touchEnded(Touch *touch, Event *event) {
}
void MyLayer::touchCancelled(Touch *touch, Event *event) {
}
void MyLayer::touchMoved(Touch *touch, Event *event) {
}

Monday, December 8, 2014

Cocos2D-X Dynamic Label Height

Setting height to 0 seems to do the trick here.

Cocos2D-X Display Long Text

When displaying long text in Cocos2D-X, it doesn't seem possible to use a single Label when the text is quite long (e.g. 2000+ characters), as the Label goes completely blank instead of displaying text. Maybe it is because Cocos2D-X uses a texture for this and this somehow blew the texture size limit. To display long text in Cocos2D-X, use multiple labels e.g. one for each paragraph.

Note: to get the height of each label so as to know where to position the next one, call "getBoundingBox()" on the label.

Thursday, December 4, 2014

Cocos2D-X: Substring

It seems like the best way is to convert to a std::string first and use its substr function, so e.g. from a Cocos2D-X String object:
cocos2dxString->_string.substr(pos,len);

Note: for Cocos2D-X 3.0 and above

Reference: http://www.cplusplus.com/reference/string/string/substr/

Git Push Specific Branch

E.g. to push master branch only:
git push origin master


Reference: http://stackoverflow.com/questions/1947972/how-can-i-push-a-specific-branch-of-git-to-my-server

Wednesday, December 3, 2014

Cocos2D-X: Conversion Between String, std::string, and C String (i.e. char*)

"String" refers to the String class (previously CCString and analogous to the NSString in Objective-C). This is for Cocos2D-X 3.0 and above.

From C String to String, it's actually the standard constructor
String* cocos2dxString = String::create(“xxxxx”);

From String to C String
cocos2dxString->getCString();

From String to std::string
cocos2dxString->_string;

From std::string to String (this requires an indirect conversion it seems)
String::create(cocos2dxString->_string.c_str());

From std::string to C String
stdString.c_str();

Tuesday, December 2, 2014

Cocos2D-X Formatting Number to Two Decimal Places

Format with "%.2f" assuming the number is a floating point type.

Reference: http://stackoverflow.com/questions/4784336/two-decimal-places-using-printf

Cocos2D-X Wrapping Text

To do that, call the "setDimensions" function on the Label. The wrapping will be done automatically. Just ensure that there is sufficient height for the additional lines.

Gimp MacOS "Embedded Color Profile"

In summary, if you don't know otherwise, convert it.

Reference: http://docs.gimp.org/en/gimp-imaging-color-management.html

Error Unzipping File on MacOS: "Error 2 - No such file or directory"

Not sure why this happens but this means the ZIP file is corrupted.

To fix it:

zip -FF zipfile.zip --out repairedcopy.zip

Reference: http://apple.stackexchange.com/questions/135853/error-opening-a-zip-file-no-such-file-or-directory

Tuesday, November 18, 2014

Friday, November 14, 2014

Linux Enable chkconfig

After creating a script in "/etc/init.d" to start/stop/restart a service, you will still need to use chkconfig to ensure that the process starts during server bootup.

To enable chkconfig, add the line in red at the top of the script in "/etc/init.d/"
#!/bin/sh

# chkconfig: 35 90 10

start(){
       # start the service here
}

# --- snipped ---


  • "35" means the service will be activated for runlevels 3 and 5
  • "90" means that the service will be started at priority 90 (bigger is later)
  • "10" means that the service will be stopped at priority 10

Tomcat Enable Self-Signed SSL

Assuming Java tools are already on your PATH:

As root user:
keytool -genkey -alias tomcat -keyalg RSA

Then answer the questions accordingly

Reference: http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html

Linux Set Time Zone

Third method on this page: http://www.wikihow.com/Change-the-Timezone-in-Linux

e.g.


ln -sf /usr/share/zoneinfo/Singapore /etc/localtime

Thursday, November 13, 2014

Linux Putting Process Into Background

When you are running a process that takes a long time and you need to logout of the server, and if you didn't run it with the "&" at the end to run it in the background, you can still send the process to the background with the following steps:

  1. CTRL-Z (This will give you your bash prompt back)
  2. If you type "jobs" you will be able to see the list of jobs (YMMV but what I saw was my process listed as "Job 1" but it was stopped)
  3. To resume it in the background, I had to tell issue the command "bg 1" (or whatever the job number is)
  4. You can also move it back to the foreground with "fg 1"

Wednesday, November 12, 2014

Monday, November 10, 2014

Enabling CORS With Cookies on Jersey

This previous post shows how to enable basic CORS functionality in Jersey. However, to enable cookies and authentication, more needs to be done. First of all the "Access-Control-Allow-Credentials" header needs to be set, then the other issue is that a wildcard "*" cannot be used with "Access-Control-Allow-Origin". You will either have to specify in hard-code the origins that you will support, or you'll have to use the Origin in the request for this response header.

Sample code:

public class SimpleCorsResponseFilter implements ContainerResponseFilter {
   @Override
   public ContainerResponse filter(ContainerRequest req, ContainerResponse resp) {
       String requestOrigin = req.getHeaderValue("Origin");
       if (requestOrigin == null) {
           return resp;
       }
       else{
             MultivaluedMap<String, Object> headers = resp.getHttpHeaders();
             headers.add("Access-Control-Allow-Origin", requestOrigin);
             headers.add("Access-Control-Allow-Credentials", "true");
             headers.add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
             headers.add("Access-Control-Allow-Headers", "Content-Type");
             return resp;
       }
   }
}

References (for the wildcard issue):

Thursday, November 6, 2014

AWS SES: Setting Sender Name

This is done by setting the same "source" field used for the email. Instead of using the email address by itself, include the name in this format "The Name <the@email.com>"

Reference:

Enabling CORS with Jersey

CORS is a framework for allowing a webpage from one site to call e.g. REST services on site.

In Java, there are open source frameworks that provides filters to support this easily e.g. http://software.dzhuvinov.com/cors-filter.html

However, for Jersey, it is actually very simple and these Servlet Filter based frameworks can be too overcomplicated / heavyweight for the need.

To enable CORS in Jersey is just a matter of implementing and registering a ContainerResponseFilter with the following:


public class SimpleCorsResponseFilter implements ContainerResponseFilter {
   @Override
   public ContainerResponse filter(ContainerRequest req, ContainerResponse resp) {
       MultivaluedMap<String, Object> headers = resp.getHttpHeaders();
       headers.add("Access-Control-Allow-Origin", "*");
       headers.add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
       headers.add("Access-Control-Allow-Headers", "Content-Type");
       return resp;
   }
}

To register this with Jersey, add the following Servlet init-params in the web.xml


<init-param>
   <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
   <param-value>xxx.yyy.zzz.SimpleCorsResponseFilter</param-value>
</init-param>

Note: code was written for Jersey version 1.17

References:

Tuesday, October 28, 2014

Fetching Large Datasets With Hibernate

The Query.list() method in Hibernate returns a List which contains all the results from the query. This works fine in most cases but if the query returns a large number of rows, memory utilisation could be an issue because the List will be a huge in-memory object.

The solution is to stream the results and scroll through them using the Query.scroll() method. For best results, the following also should be done:

  • Scroll with ScrollMode.FORWARD_ONLY
  • Use a StatelessSession (to avoid caching)
  • Set fetch size to Integer.MIN_VALUE (this one I'm not 100% sure about, but it's recommended in some blogs)
References:

Sunday, October 19, 2014

Open Source Columnar Databases

Columnar databases are actually SQL databases with a different storage format where data is organised according to columns rather than rows. This is far more optimal for fact table queries.

If cloud hosting is a the only option, then the best solution is probably Amazon Redshift. However, if you need to install and operate your own the open source options (which have not been evaluated) are:

If these are not suitable, there is also a commercial option in Infobright: https://www.infobright.com/

Wednesday, October 8, 2014

Google Drive Revoke Shares to All Documents for User


  1. From the list of folders on the left, find an item that says "All Items"
  2. Check all items
  3. More -> Share
  4. You will see the list of all users that you have shared documents with, just delete the user from the list

Monday, September 8, 2014

Comparing Java Template Engines

This is more for general purpose use-case other than just for building web-apps e.g. creating HTML for EDMs.

A great guide here: http://www.slideshare.net/jreijn/comparing-templateenginesjvm

In summary:

  • If you need a designer-friendly system:
    • Thymeleaf
    • Mustache
  • If you are a stickler for the DRY (Don't Repeat Yourself) principle:
    • Jade generates HTML from scripts
  • Or if you prefer something more developer-friendly:
    • Freemarker
    • JSP listed as an option by presenter also
In my view, having something designer-friendly is why you use a temple engine in the first place. So the shortlist came down to Thymeleaf and Mustache, and Mustache wins out for simplicity and performance. Note though that Mustache may be too simple for some of your needs.

Friday, September 5, 2014

HTML Email Best Practices

The Internet community hasn't been totally unanimous on this but this seems to be the general consensus:

  • The DocType declaration should be there and it is recommended to use the XHTML 1.0 Transitional
  • It is recommended to use a fully formed HTML document with <html> and <body> tags
References:

HTML vs Plain Text Emails

These days both HTML and Plain Text emails have similar levels of deliverability, but with HTML emails there are the following concerns:

  • If HTML has errors and results in formatting issues and user can't read email properly, user may mark it as spam
  • If HTML email contains too much pictures and too little text there is a higher chance of spam filter marking is as spam
References:

AWS SES Send HTML Email With Java API

It is not clear in the documentation whether it is possible to send a multi-part email with both Plain Text and HTML components via AWS SES.

I did a test and verified that it is supported in this way:
Body body = new Body();
Content textContent = new Content().withData("text content");
body.withText(textContent);
Content htmlContent = new Content().withData("html content");
body.withHtml(htmlContent);

The resulting email will be a multi-part email with both Plain Text and HTML components.

Sunday, August 31, 2014

AWS EC2 Creating New Instance with Image Created from Snapshot

When I tried to do this, I encountered an error (which I saw in the System Log):
error: couldn't mount because of unsupported optional features (240)

This is due to ext-fs compatibility issues, which is in-turn caused by trying to boot the server up with an incompatible kernel ID.

To fix this, go to the original instance and note down the kernel ID (be sure to take this down every time you create an AMI to be used to create instances) and use this kernel ID when you are creating the AMI.

Reference:

Wednesday, August 27, 2014

Increase Disk Size in VirtualBox

First of all if the virtual disk is using the VMDK format, it needs to be converted to the VDI format. Unfortunately, this can't really be done, at least not on the original virtual disk. You'll have to make a clone of it. After detaching the drive from the VM via the VirtualBox GUI, do this on the command line on the host system.
VBoxManage clonehd old-disk.vmdk new-disk.vdi --format VDI --variant Standard

Then, resize the clone to e.g. 100GB
VBoxManage modifyhd new-disk.vdi --resize 100000

Attach this virtual disk to the VM but at this point, the VM will not have access to the extra space. It needs to first be added as a partition and the recommended way to do this is to use the GParted live CD. Download the ISO file and then assign it as the CD to boot from in the VM. Make sure that the boot order of the VM is to boot from CD first. Both these steps are done via the VirtualBox GUI.

In GParted, assign the new space to an existing or new partition. After this, shutdown the VM, remove the CD (i.e. ISO) from the CD, and boot up the VM again.

The following steps are for CentOS users who have LVM setup by default. The next step is to configure the LVM to use the additional space for the volume. Here, I added 90GB to the LVM volume from the device /dev/sda2.
lvextend -L +90G /dev/mapper/vg_thevm-lv_root /dev/sda2

After this, the final step is to make the ext3 filesystem use the extra space.
resize2fs -p /dev/mapper/vg_thevm-lv_root

After this, do a "df" and you should see the extra disk space available.

References:

Tuesday, August 19, 2014

MongoDB Delete Items from Array

It is possible to delete items from array based on very specific criteria using $pull.

Works for both primitives in an array or complex objects in the array.

Reference: http://docs.mongodb.org/manual/reference/operator/update/pull/

Tomcat Suppress Stacktrace on Status 500 Error Page for REST Services

Whenever there is a HTTP Status 500 error, Tomcat by default displays an error page with the stacktrace on it. In production servers, this should be disabled. One common way to do this is to specify custom error pages in web.xml, like this:
<error-page>
<error-code>500</error-code>
<location>/error-500.html</location>
</error-page>

This works in most cases, but for a lot of Java REST backends, all URLs are mapped to the REST framework. For example, with Jersey, all URLs are mapped to the Servlet handling the REST requests.
<servlet-mapping>
<servlet-name>RestServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
In this situation the above solution will fail because RestServlet is unable to serve "error-500.html".

The solution is to use another Servlet to handle error paths. For static files, the "default" Servlet works. In order for Tomcat to use the default Servlet for error pages, this has to appear before the RestServlet in web.xml.
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/error*</url-pattern>
</servlet-mapping>

However, there is a problem with this solution. If the original REST request is a PUT, the default Servlet will reject it with a 403. The solution is to create a custom error handling Servlet that does not process the request but instead prints out the error page depending on the error code embedded in the request URI. This is a Servlet that overrides doGet, doPost, doPut and doDelete, and within each of them, outputs the appropriate error page using out.print().

Thursday, August 14, 2014

MongoDB Sorting

Mongo DB command line:
db.collection.find().sort( { score: -1 } )

Mongo DB Java driver:
DBCursor cursor = collection.find();
cursor.sort(new BasicDBObject("score", -1));

Note that "-1" has to be an int, not a String

Reference: http://docs.mongodb.org/manual/reference/operator/meta/orderby/

MongoDB Index

Single field index: http://docs.mongodb.org/manual/core/index-single/

Compound index: http://docs.mongodb.org/manual/core/index-compound/

Thursday, August 7, 2014

Bitnami Wordpress Root

Here it is: "/opt/bitnami/apps/wordpress/"

Wordpress Pingback Attack

This attack makes use of the pingback/trackback feature to generate a lot of traffic to a target via many third-party uncompromised Wordpress servers. This is because when this request is made (via xmlrpc.php) to a server, it will attempt to download data from the target server.

These links describe the attack:
Here are some suggested solutions:

Cocos2D-X HttpClient: Adding HTTP Headers

It's done like this:
std::vector<std::string> headers;
headers.push_back("Content-Type: application/json; charset=utf-8");
request->setHeaders(headers);

Reference: http://www.snip2code.com/Snippet/15942/HTTP-Client-for-Cocos2dx

Cocos2D-X: Basic Guide to Using HttpClient

This guide is pretty much covers the basics: http://www.cocos2d-x.org/wiki/How_to_use_CCHttpClient

The only part lacking is the signature of the callback, which needs to have 2 arguments. Example:
void onHttpRequestCompleted(cocos2d::network::HttpClient* client, cocos2d::network::HttpResponse* response);

Blog Post Comparing JSON Libraries in C++

Link: http://www.thomaswhitton.com/blog/2013/06/28/json-c-plus-plus-examples/

Covers:

  • jsoncpp
  • rapidjson
  • jansson

Using Rapidjson in Cocos2D-X: Creating a JSON Document in Code and Serializing it

This is based on Cocos2D-X version 3.2

This import is necessary for creating a JSON document and manipulating it:
#include "external/json/document.h"

These imports are necessary for Serialization:
#include "external/json/writer.h"
#include "external/json/stringbuffer.h"

Example code:
rapidjson::Document jsonDoc; // create the object
jsonDoc.SetObject(); // flag it as an object rather than an array,a necessary step for Serialization

// to set a value (using Cocos2D-X String type in this example here)
String* key = “key”;
String* value = “value”
jsonDoc.AddMember(key->getCString(),value->getCString(),jsonDoc.GetAllocator());

// to Serialize to JSON String
rapidjson::StringBuffer sb;
rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
jsonDoc.Accept(writer);
String* jsonString = String::create(sb.GetString());

References:

Enabling HttpClient in Cocos2D-X in Android

To do this, you'll need to uncomment the following lines in Android.mk

LOCAL_WHOLE_STATIC_LIBRARIES += cocos_network_static
and
$(call import-module,network)

Otherwise you'll get error messages saying HttpClient cannot be found.

Android Error "Binary XML file line #xxx: Error inflating class "

There seems to be many causes of it but one of them seem to be out of memory error, just bad error handling and unclear error message:

References:

Cocos2D-X 9 Patch Technique with Scale9Sprite

Links:

The key thing step here is the "setCapInsets" function.

Cocos2D-X 3.0: What's New

As summarised in this blog post http://www.cocos2d-x.org/news/216 :

  • A lot of refactoring with "CC" removed from many class names, the API design being more C++ than just a straight port of Cocos2D etc
  • Huge performance improvements (or so they claim)
  • New UI widget collection
  • Many many more

Cocos2D-X 3.0 Changes Part 1

A lot of refactoring was done moving to Cocos2D-X 3.0, with a lot of renaming being done, making it difficult to map old classes to new ones. Here are some observations and notes:

  • CCObject has been removed, if you wish to create an object that supports auto-release and reference counting, use "Ref" instead.
  • CCLOG doesn't seem to work anymore (nothing showed up in Android logcat), but switching to use "log" worked fine.
  • CCString is now just "String" (this is a bit confusing as you don't exactly find a "String" class in the API references)
  • CCPoint is now Vec2
  • Generally CC has been removed from many class names, but some classes (such as those above), have been completely renamed

Wednesday, August 6, 2014

Mac OS SVN

No longer installed by default (Mac OS 10.8.X). To install, open XCode, then Preferences, go to the Downloads tab and install "Command Line Tools".

Reference: http://blog.grapii.com/2012/08/svn-missing-in-mac-os-x-10-8-mountain-lion/

Monday, August 4, 2014

Cocos2D-X Creating Solid Color Rectangular Sprite

There are times where instead of overriding the "draw" method, you need to create a sprite that is a solid rectangle. There are a few ways to do it, but the easiest for me is to create a 1x1px PNG file. The color can be changed during runtime as needed.

Reference: http://stackoverflow.com/questions/3339955/cocos2d-solid-color-rectangular-sprite

Android "gravity" vs "layout_gravity"

"gravity": affects layout of children within the view

"layout_gravity": affects the layout of the view within its parent

Reference: http://stackoverflow.com/questions/3482742/android-gravity-and-layout-gravity