Tuesday, March 24, 2015

Spring REST and wildcard url-pattern in web.xml

The wildcard url-pattern '/api/*' in web.xml doesn't work with Spring REST @RequestMapping's absolute path like '/api/customers'.
@RequestMapping's relative path without any leading slash like 'customers' does work.

In web.xml
  <servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/api/*</url-pattern>
    <url-pattern>*.htm</url-pattern>
  </servlet-mapping>

In your java source code
 @RequestMapping( "customers" )

Now you can use the URL 'http://myserver.com/api/customers'.

Sunday, December 7, 2014

Gitblit with Active Directory

[ERROR] Error Connecting to LDAP
LDAPException(resultCode=49 (invalid credentials), errorMessage='80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db1 ', diagnosticMessage='80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db1 ')
This could be the wrong password.
So I tested with my personal Active Directory account and it worked.
realm.authenticationProviders = ldap
realm.ldap.server = ldap://192.168.0.2
realm.ldap.username = [DOMAINNAME]\\duncansungwkim
realm.ldap.password = [YourPassword]
realm.ldap.accountBase = CN=Users,DC=[domainname],DC=[your-org],DC=com
Any Active Directory account in the "Domain Users" group will work.
In fact, you should ask your Active Directory administrator for the password of a special account that is only for anthentication. That account should be only in the "Domain Users" group, which I believe has the least rights.

Tuesday, April 1, 2014

Workaround of git Shallow Clone with Submodules

You can clone a git repo only with the most recent revision by using git's "shallow clone" as the following
command.
$ git clone --depth 1 https://github.com/MyRepo.git

If you have submodules, you would use the option --recursive as follows
$ git clone --depth 1 --recursive https://github.com/MyRepo.git
And you would expect that the submodules are also shallowly cloned, but they are actually full clones.

You can work around this problem by using consecutive commands in one line like the next
$ git clone --depth 1 https://github.com/MyRepo.git ; cd MyRepo ; git submodule update --init --depth 1
If you use Windows, use &(ampersand) instead of ; (semicolon).
C:\> git clone --depth 1 https://github.com/MyRepo.git & cd MyRepo & git submodule update --init --depth 1
This is such a primitive solution. However, this was really a good tip for using git for build automation.

One of my build jobs kept failing with the following error message.
error: RPC failed; result=56, HTTP code = 200
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed

It is said that this problem is caused by too big a git repo, maybe with over 20MB. I had big submodules but they were big due to its history. So I thought of the shallow clone, but it didn't work because git doesn't propagate the depth setting to the submodules when I use --recursive option. I couldn't wait for a new git version to fix this. Now I divided and conquered it.

Tuesday, December 3, 2013

C++ Exception Finally stand in

C++ has no equivalent of "finally" in the exception handling construct. So I wrote a class named Finally which can be used instead as "finally" in other languages. This only works in C++11 because this makes use of lambda.
#include <functional>
#include <array>
#include <assert.h>

template< std::size_t N >
class Finally
{
public:
    Finally() : m_uCount(0) {}

    typedef std::function<void()> deleter_type ;
    void operator += ( const deleter_type&& a_deleter )
    {
        assert( m_uCount < N ) ;
        if( m_uCount >= N ) return ;
        m_deleters[m_uCount++] = a_deleter ;
    }

    ~Finally()
    {
        for( int i=int(m_uCount)-1 ; i>=0 ; --i )
        {
            m_deleters[i]() ;
        }
    }

private:
    std::array<deleter_type,N> m_deleters ;
    size_t m_uCount ;

    Finally( const Finally& ) /* = delete */ ;
    Finally( Finally&& )  /* = delete */ ;
    void operator=( const Finally& ) /* & = delete */ ;
    void operator=( Finally&& ) /* & = delete */ ;
};
Following is a code snippet which my Finally class is applied to.
#include <stdlib.h>
#include "Finally.h"

void Test( int a_iException )
{
    Finally<3> finally ;
    FILE* pFile = ::fopen( "Test", "w" ) ;
    finally += [ pFile ]
    {
        if( NULL != pFile )
            ::fclose( pFile ) ;
    } ;

    try
    {
        if( 2 == a_iException )
            throw 2 ;
    }
    catch( std::logic_error& e )
    {
         throw ;
    }
}

int main()
{
    try
    {
        Test( 1 ) ;
        Test( 2 ) ;
    }
    catch( int iExc )
    {
        assert( 2 == iExc ) ;
    }
    return 0 ;
}

Tuesday, October 9, 2012

SmartSVN External Conflict Solver Arguments

KDiff3

${leftFile} ${baseFile} ${rightFile} -o ${mergedFile}

Wednesday, August 1, 2012

Select All the Keys at One Frame in Curve Editor

Whenever I used [Curve Editor] in 3ds Max, I always wondered why I couldn't easily vertically select all the keys at one frame. Now I have figured out the easy way. I should use [Track Bar] for it. Because [Track Bar] is away from [Curve Editor], they seemed to be so unrelated that I couldn't realize it, but the method seems to be official.
I'll show you the picture. Note those red rectangles.
As shown in the picture, if you select a collective key on [Track Bar] at the bottom, it gets highlighted and the corresponding keys in a pillar in [Curve Editor] in the separate floating window also get highlighted.
You can also move a pillar of keys in [Curve Editor] by grabbing and dragging the correspodning collective key on [Track Bar].
As a matter of fact, you don't need to use [Curve Editor] so as to deal with the all the key at one frame. You have only to use [Track Bar] for it.

Tuesday, July 31, 2012

Cut an Action of Biped Animation

If you animate a biped for a video game, you have to arrange a series of short discrete actions of the biped one after another in a row on one single timeline. When you export the biped animation, you give each of the actions a start time, an end time and a unique name and then the video game identifies each of the actions by the name to play it. The data is represented so that an action comes after the previous action has finished playing. One action is definitely not along the continuity from the previous one and on to next one even though they are so arranged.
Here is a serious problem with 3ds Max 2011. 3ds Max 2011 doesn't provide you with the method that splits the animation sequence of a biped into discrete actions. When you have finished making a action and freshly start making a new action, you will find that your new keys somehow affect the movement of the previous action. How strange it is! That is because 3ds Max tries to help smooth out your animation between your keys. This is known as interpolation, which has been done for every key of any biped movement in the previous action. So it also smoothes out between the last key of the previous action and the new key of the new action. If the last key of a part of the biped is up front in the previous action, away from the new key of the next new action, things look worse. That's not what you want. You want to stop affecting the previous action.
Unfortunately I couldn't find such an option as no interpolation for biped keys. If it were not for a biped, you could use [Set Tangents to Step] in [Track View-Curve Editor]. Alas, it doesn't work for bipeds. How can you sever the previous action and isolate each action. 

I finally came to use two redundant keys which confine the unintentional interpolation between them. Here is how I do it.
  1. Let's say you have finished the first action of a biped animation.
    Let's assume you have finished it at frame 50. Move the time slider onto the 50th frame. Make sure you are in [Auto Key] mode.

  2. Let's select all the tracks of your biped's Center Of Mass(COM).
    Click any part of the biped in one of the viewports. Note those pink rectangles in the right figure. At the top of the right column, click Motion tab to activate Motion panel and find [Track Selection] roll-out on it. Click the fourth button, [Lock COM Keying] with the lock icon on it in the roll-out and you will see it turned into yellow like it is pressed. Click all the three buttons to the left of [Lock COM Keying] button and all the three buttons also turn into yellow.

  3. Let's select the whole biped.
    Note those red rectangles in the figure below. Open [Schematic View] by clicking [Schematic View(Open)] button, the 5th button from the right of the main toolbar. Find the root node of the biped's tree diagram and double-click it to select all the parts of the whole biped.

  4. Let's manually set keys.
    Make sure you don't lose the selection. Note those yellow rectangles in the right picture above. Go to to Motion panel and open [Key info] roll-out. Click [Set Key] button, i.e. the first button so as to set the keys over the whole biped.

  5. Let's copy all the keys at the finishing frame to the next frame.
    Make sure again that the whole biped is still selected. At the bottom of the main window with the viewports, click the collective key at frame 50 on [Track Bar] under [Time Slider] and it will get brighter to indicate it's selected. Press and hold Shift key on your keyboard and meanwhile click and drag the selected key, i.e. the 50th and release your mouse at the very next frame, i.e. 51st. Now the finishing key is copied as shown in the next picture. Note the two black squares at 50, 51 in the next picture.

  6. Let's release [Track Selection] buttons.
    Back to Motion panel, click the yellow [Lock COM Keying] button to turn it into the previous color and then toggle off the three buttons to the left of [Lock COM Keying] button. All the four buttons should not be yellow.

  7. Start working a new action from the second next frame.
    Move the time slider onto the second next frame, i.e. the 52nd. Start your new action. The previous action will not be affected at all by the next new action.

Now we can delimit each action of a biped in order to separate them on one single timeline.