tag:blogger.com,1999:blog-28583286903003815702024-03-04T21:28:41.722-08:00eSpaceLeaking thoughts out of eSpaceSamer El Sahnhttp://www.blogger.com/profile/07314985878394159062noreply@blogger.comBlogger55125tag:blogger.com,1999:blog-2858328690300381570.post-82512101383115689082008-02-05T08:57:00.000-08:002008-02-05T08:59:15.537-08:00One template file for all pages using Servlets and JSPOne of my recent tasks was making a new skin for one of our websites. the site had a common header, left side area and right side area that are to be shared among all pages. we used to include file for "header", "left side", "right side" in each of the pages.. it wasn't that pretty i know.<br /><br />I wanted to think of something better where i can define the template in exactly one file and i do not have to include that file on every new page i add. something pretty much close the RubyOnRails "<% yield %>' directive to import the page content inside the template. i finally managed to do it.<br /><br />I'll use two simple pages to illustrate the concept:<br /><br />mahmoud.jsp<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHcGtbvOcMzhnVlq3w2EWHJ0T44SlQTGJj4zcfDhnoVFVlDcyevxrgn5fWC1nGw1QzX0EVqIwROuPSv7d9h5rnoN_Nt0Dsm_MJS5Mgpt6kcSePMZ6xy9LVgsYd8-ZoZ06Dk7DnQNHfvOI/s1600-h/Screen-mahmoud.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHcGtbvOcMzhnVlq3w2EWHJ0T44SlQTGJj4zcfDhnoVFVlDcyevxrgn5fWC1nGw1QzX0EVqIwROuPSv7d9h5rnoN_Nt0Dsm_MJS5Mgpt6kcSePMZ6xy9LVgsYd8-ZoZ06Dk7DnQNHfvOI/s320/Screen-mahmoud.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5163531558367018658" /></a><br /><br />and index.jsp<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSClv2CxyM9xqg8ogcFo22ldnLdBmgK0H2-BLVpC0jwEz5nmEk4TIDXHV-ZlB3yd46FeHZ4wKabaZixq-1vOc749Q2urYYFJQ7R0K0xV89jyCCBUyT3Uxdlvb4MylnDyLUENnI4k0Vb9o/s1600-h/Screen-index.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSClv2CxyM9xqg8ogcFo22ldnLdBmgK0H2-BLVpC0jwEz5nmEk4TIDXHV-ZlB3yd46FeHZ4wKabaZixq-1vOc749Q2urYYFJQ7R0K0xV89jyCCBUyT3Uxdlvb4MylnDyLUENnI4k0Vb9o/s320/Screen-index.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5163531807475121842" /></a><br /><br /><br />what we want is to have each of the two pages displayed in a layout where is one header, banners and so. which will look like the following.<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhStrNvf6I-7iNiiFYC0f950RuecptPeV32uBcAfbXGTXa29Cc4Kj-j7zupf-F3545P0XfVZscdSzHMQmbGmjUIoJMPaYf3rbgpHP3FlMW8gYdHRYLdaqvSueI4p_v7WLykQ-hWUAk0FzA/s1600-h/Screenshot-mahmoud.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhStrNvf6I-7iNiiFYC0f950RuecptPeV32uBcAfbXGTXa29Cc4Kj-j7zupf-F3545P0XfVZscdSzHMQmbGmjUIoJMPaYf3rbgpHP3FlMW8gYdHRYLdaqvSueI4p_v7WLykQ-hWUAk0FzA/s320/Screenshot-mahmoud.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5163532228381916866" /></a><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj188HAxakxUgElCzrdgF83pzklSrwACateO-VMgY_7wE1uVsJ7pWgFgWpnnlvuGmmX6dreKLLL2KAFTT9mnRxMMz4xH-vEI6cEVQ9wwT41kliZHsgaJBKkJ9gHIH_AOaJww9OZiPxqxqA/s1600-h/Screenshot-index.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj188HAxakxUgElCzrdgF83pzklSrwACateO-VMgY_7wE1uVsJ7pWgFgWpnnlvuGmmX6dreKLLL2KAFTT9mnRxMMz4xH-vEI6cEVQ9wwT41kliZHsgaJBKkJ9gHIH_AOaJww9OZiPxqxqA/s320/Screenshot-index.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5163540801136639762" /></a><br /><br /><br />I was able to do this using a servlet that intercepts the request. and loads the template jsp file and pass the desired page to as a parameter to be included.<br /><br />The template file is called <span style="font-style:italic;">template.jsp</span> will look like:<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEP9lJdqGWFPHyxDO1jKNwwJILQyaQ1wwg8cCHXlJQ2WzQjEqd9Fc7lFNzjDwCV_XEhlQvvmh_qR9gP2qdgypbvzX0QceLV_3XnM0QM7cPE_Hoe97Ybk2u1Ujd2IKHFR9jjMqGsgaHzsk/s1600-h/template.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEP9lJdqGWFPHyxDO1jKNwwJILQyaQ1wwg8cCHXlJQ2WzQjEqd9Fc7lFNzjDwCV_XEhlQvvmh_qR9gP2qdgypbvzX0QceLV_3XnM0QM7cPE_Hoe97Ybk2u1Ujd2IKHFR9jjMqGsgaHzsk/s320/template.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5163533104555245266" /></a><br /><br />The only line that matters in the template code is where we make the jsp:include page="<%request.getParameter("targetPage")%>"<br /><br />The servlet intercepts http requests and loads this template using RequestDispatcher and passes the original desired page as a parameter:<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl1-hnh-R5Fose9bp-f88Gj0Ts7XdIK9k-mr58NffI_5B7sUGuBJxbTcBv56rMd6T29HR3S8W6bh7P32ARSMwuZpSCJEU2MiAwukC3XPMzADxidIlbK5HGSsFMsWElYbw_8dggqwLwvQ8/s1600-h/servlet.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl1-hnh-R5Fose9bp-f88Gj0Ts7XdIK9k-mr58NffI_5B7sUGuBJxbTcBv56rMd6T29HR3S8W6bh7P32ARSMwuZpSCJEU2MiAwukC3XPMzADxidIlbK5HGSsFMsWElYbw_8dggqwLwvQ8/s320/servlet.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5163540517668798210" /></a><br /><br /><br />The Servlet and servlet mapping in web.xml will look like<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4XfjO5k_a_wP01ZlWz0yRpI6I0cZ8W-JE2oKgidRT5UAFAC2eMI9W1yVUArCfGTsqqld0qOEEthI4MPxYGYl_-VWeNBZJkmYoKk3pxKTyBm-maOwx6XWknF1v7NEA5JZJB8d0BalzB4U/s1600-h/web.xml.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4XfjO5k_a_wP01ZlWz0yRpI6I0cZ8W-JE2oKgidRT5UAFAC2eMI9W1yVUArCfGTsqqld0qOEEthI4MPxYGYl_-VWeNBZJkmYoKk3pxKTyBm-maOwx6XWknF1v7NEA5JZJB8d0BalzB4U/s320/web.xml.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5163536974320778994" /></a><br /><br /><br />A note to be mentioned is that I had to configure my template to be initiated with requests to html pages (i can choose to work on any extension except jsp). When I configure my servlet mapping to be associated with jsp URLs, i get stuck in an infinite loop as since including the page inside the template results in a new jsp request.<br /><br />The idea is simple. You are free to create your own template and to work on any file extensions in the url, but you have to specify a type other than jsp to avoid the infinite loop trap.<br /><br />Bon appetitemahmoudhttp://www.blogger.com/profile/09457586853819956435noreply@blogger.com3tag:blogger.com,1999:blog-2858328690300381570.post-84681946321660823352008-01-06T14:40:00.000-08:002008-01-06T14:42:06.356-08:00Restful Pagination in RailsHave you ever tried to cache your paginated lists? Sadly, vanilla Rails wont help much as they ignore the url query parameters when caching and hence the page=x value is not honored and Rails caching (action or page caching) will simply stick to the first page rendered for all requests.<br /><br />One might come with a solution that overrides the cache key generation to incorporate the query string, which will work, but will result in very long and ugly hash keys.<br /><br />Luckily there is a better approach, if you simply defined routs for pages (for the paginated resources) and name them page parameter with the same name you give it in the paginator then Rails will pick up the route when creating paginated links. <br /><br />In your routes.rb<br /><br />map.resources :users<br />map.paged_users '/users/pages/:page'<br />map.formatted_paged_users '/users/pages/:page.:format'<br /><br />once the above routes are in place, all you need is to make sure your paginators are using 'page' as the page parameter name and you will see the pagination links created like this:<br /><br />/users/pages/1<br />/users/pages/2<br /><br />Don't forget the formatted route to support pagination with various formats so you can use routes like:<br /><br />/users/pages/1.xml<br /><br />These urls are very cache friendly and adhere to REST much more than the default parameters based ones.<br /><br />Happy caching (with pagination)oldmoehttp://www.blogger.com/profile/14341721253106429644noreply@blogger.com0tag:blogger.com,1999:blog-2858328690300381570.post-44624489167287200212007-11-03T14:03:00.000-07:002007-11-03T14:08:28.970-07:00Installing Windows, Ubuntu7.10, Mac OS 10.4.10 on MacBook (Triple Boot)<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwC_oK_maGtXHYrfCTjuGN3mdsd_Q9YkOovdC8T0mdwAE4bLxBPqtXWbuzWTqakFkpJHinGLW8TxN1FSPQFRUSqKCSmNN8Vrp4VEO_ApXXsJYCmIN3Z43LoiQagCyubuapCWI04zIRE5c/s1600-h/IMG_0349.JPG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwC_oK_maGtXHYrfCTjuGN3mdsd_Q9YkOovdC8T0mdwAE4bLxBPqtXWbuzWTqakFkpJHinGLW8TxN1FSPQFRUSqKCSmNN8Vrp4VEO_ApXXsJYCmIN3Z43LoiQagCyubuapCWI04zIRE5c/s320/IMG_0349.JPG" alt="" id="BLOGGER_PHOTO_ID_5128704478436125282" border="0" /></a><br />I am happy with my MacBook with its running Mac OS X 10.4.10. I can't stand working on windows any more, I feel more comfortable with Mac OS.<br /><br />My master Thesis is running on linux environment(basically Fedora, but I successfully turned it to be Ubuntu)<br />My current project delivery should be done on windows. An easy solution costing 60$ would be to purchase <a href="http://www.vmware.com/beta/fusion/">Fusion</a>.<br />Although Fusion looks very interesting, I didn't submit to this solution, for the following reasons:<br /><ol><li>Running virtual machines consumes more memory, in this case I will loose some performance which is something I will certainly need during development.</li><li>More memory usage, means more power consumptions, hence less battery life time. in normal cases I enjoy having ~4hrs battery life time with my lovely Mac. this is sthg i don't stand to loose.</li><li>to overcome the first problem, I can extend my RAM. this will make the virtual software costs me almost (60+90)$....I really can't afford this for now. (I didn't get paid for salary 3 months ago)</li></ol>So, I decided to to create a triple boot on my MacBook. It was a very risky step for me..But here we go, I have nothing to loose anyway (keeping in mind 150$ :S, 900 LE when converted to our local currency!!!!!! )<br /><br />My MAC specs are:<br />Processor: 2.16GHz Intel Core 2 Duo<br />Memory: 1 GB 667 MHz DDR2 SDRAM<br />MAC OS X: 10.4.10<br /><br />The target is to install Ubuntu 7.10 and WinXP SP2 on MacBook.<br />steps:<br /><ol><li>Get <a href="http://www.apple.com/bootcamp/">BootCamp</a>: I think it may force you to update to Mac 10.5. (luckily I installed it 1 month ago before leopard is released)</li><li>Update your Mac OS.</li><li>Install <a href="http://refit.sourceforge.net/">rEFIT</a>.</li><li>run BootCamp assistant and follow instructions to burn driver CD for windows. (don't proceed with installing steps)</li><li><a href="http://wiki.onmac.net/index.php/How_To_Backup_your_Mac">Backup</a> your data. (you may not loose your data if things go smoothly)</li><li>Check your disk partitions and identify the Mac Partion. I most cases it is /dev/disk0s2. but if you are not sure, you can verify this by running a shell command using the diskutil: <pre size="12px" color="black" style="border: 1px dotted black; padding: 6px; background-color: rgb(255, 255, 204);">$ diskutil list<br /></pre> resize your HDD using Diskutil by running the following command. first you specify the volume to be resized, and its new size, then the type, and the name of the new volumes followed by their size.<br /><pre size="12px" color="black" style="border: 1px dotted black; padding: 6px; background-color: rgb(255, 255, 204);">$ diskutil resizeVolume /dev/disk0s2 70G "Linux" "Linux" 20G "MS-DOS FAT32" "Windows" 20G<br /></pre></li><li>insert your XP SP2 CD and hold down the "ALT" key.</li><li>install XP on the valid partition, just give it a quick FAT32 format.<br /></li><li>you should now have a dual boot(windows with Mac).</li><li>insert your Ubuntu 7.10 Live CD.</li><li>run the installation normally. You should set up the partition manually. Don't mount the EFI system partition. you need only to mount / to the drive you allocated to your linux installation. I didn't make a SWAP file, I just don't need this for now, I relied on my 1GB RAM.</li><li>Continue through the installation steps.</li><li>When you reboot, you should have triple boot.<br /></li></ol>Ahmed Abd-ElHaffiez Husseinhttp://www.blogger.com/profile/09563341584184001660noreply@blogger.com1tag:blogger.com,1999:blog-2858328690300381570.post-16212597270166054232007-11-03T02:02:00.000-07:002007-11-03T02:07:22.102-07:00Why Software Developers Leave...i read a nice article with the title "<a href="http://www.developerdotstar.com/mag/articles/software_team_turnover.html">Software Team Turnover: Why Developers Leave (And What You Can Do About It)</a>".<br /><br />In this article, the writer, Aaron Reed, discussed the negative impact of the fact that some software developers leave their teams and what makes them do that. it is worth to read.<br />Aaron specified three main reasons that causes developers to leave:<br /><br /><span style="font-weight:bold;">Money</span><br />Like any person in any field, Software Developers too are in need for Money to fulfil their human needs. a developer being paid below the market average might be an unhappy unsatisfied developer. and in general, a Developer can increase his income by jumping to a new place more that he can by getting a raise in the same place.<br /><br /><span style="font-weight:bold;">being happy with what they do</span><br />Developer can work in some place or on some project even under paid, if they love what they are working on. in other words.. they also can leave for somewhere else (even paying less) if they were unhappy about they current projects/place/team, if they were bored, or if they were <span style="font-weight:bold;">not learning more</span> and not getting experience. actually this is a key reason for developers to move to a new place. the need for getting new experiences and new challenges.<br /><br /><span style="font-weight:bold;">Burnout</span><br />Software development is not an easy job. It is like having a hard exam for at least 8 hours per day/ 5 days per week. sometimes the developer gets overloaded by working in some project, and due to his experience in that project or field, and due to the fact that resources are need for that project. management do not move the developers to another project. which makes leaving the whole place is the only get away for the developer. i have seen this more than once before.<br /><br />i totally Agree with Aaron Analysis of the issue. but i also need to add <span style="font-weight:bold;">"Politics"</span> as a candidate cause itself. a broken promise from the management side is fatal from the developer's prospective. disharmony among team members or people in the same work place may cause some of them to be unhappy to the extent that they may not want to stay in that place any more. of course that last reason is not specific to software developers, but it matters and do worth mentioning. actually all of the reason aren't specific to them.mahmoudhttp://www.blogger.com/profile/09457586853819956435noreply@blogger.com0tag:blogger.com,1999:blog-2858328690300381570.post-17460590647379905092007-10-31T01:30:00.000-07:002007-10-31T01:31:40.205-07:00Effective Java ProgrammingEffective Java Programming, by Addison Wesley, is one of nice books i have read in software development material. and i recommend it to any developer developing in Java, starter or senior.<br /><br />programming by nature is very flexible. you have many choices. it is like creating a statue using clay. You choose at every point; Class names, methods and variable names. public methods, internal implementation algorithms, structure of the package classes,.. all of those and others are left for the programmer to choose.<br /><br />Effective Java programming comes to introduce a lot of the best practices for Java programmers; to enhance the stability, readability, clarity, reusability and maintainability of their code. it also has guides to the proper use of a lot of the java standard classes.<br /><br />A note inside the book really draw my attention; in item 8, chapter 3, Wesley was talking about overriding the hashCode method, he stated an example of a phone number class and an implementation of a suggested hashCode, then he said "Writing such hash functions is a topic of active research and an activity best left to mathematicians and theoretical computer scientists.". Wesley encourages his readers to use the state-of-art code. that's the goal of the book.<br /><br />Actually i was thinking about the classes of the open source libraries we use as i proceeded reading the book. the kind of code that shall be used by thousands of programmers all around the world.mahmoudhttp://www.blogger.com/profile/09457586853819956435noreply@blogger.com0tag:blogger.com,1999:blog-2858328690300381570.post-27040929175585932912007-09-27T02:47:00.000-07:002007-09-27T03:50:52.576-07:00To AJAX or Not to AJAX? That is the question!<p>When faced with a new web project these days you typically hear the clients listing AJAX as one of the must haves in their brand new web application. Pretty cool as you might be accustomed yourself to AJAX to the extent that you can hardly imagine returning back to the page reload per click days. But, if you are more sensible (or better yet, your clients are so) you would think twice before entirely abandoning the normal site browsing model for an AJAX based one.<br /><br /></p> <p><br /> Why? I hear you say. Many reasons, including the fact that we live in the early 21st century, where – get ready for this – not all Internet access devices are equipped with state of the art browsers that can consume your AJAX interfaces or whatever Javascript or CSS magic you throw at them. Many mobile phones (millions to say the least) can hardly parse plain old HTML, some can do CSS but not Javascript<br /><br /><br /> Ok, you tell me. “I will have to do two versions, one that is full of AJAX effects and one old boring HTML only version.” STOP IT, I say, you can't be more wrong. Thank God there could be more elegant solutions to the problem than just writing another application around the same database. I present to you my humble take on the problem. Using the Ruby on Rails Framework (you can apply similar thoughts in other frameworks if you like, and many ideas can be copied easily as they only involve Javascript)<br /> </p><p> First off, the controllers. The controllers are responsible for receiving requests and sending responses. What we need to do is make them intelligent enough to understand different types of requests and respond accordingly. This is done using Rails magical method “respond_to”<br /> </p><pre>class IssuesController < ApplicationController<br /> def index<br /> ...<br /> respond_to do |format|<br /> format.html { # do something }<br /> format.js { # do another thing }<br /> format.json { # and another thing }<br /> format.xml { # ok, enough }<br /> end<br /> end<br /> ...<br />end<br /></pre><p> In the above example we see that each format will have a different response. This is great for a start, that way we can implement slightly varying responses for the AJAX and the none AJAX calls. To make things easier on us we will implement a very simple case of AJAX. Each rhtml view is rendered in a DIV tag within an rhtml layout. In the none AJAX model, pages are rendered by rendering both the layout and the inner view. In the AJAX model, only the inner view is rendered and is sent back to the browser to replace whatever resides in the content DIV.<br /> </p><p> So, our controllers will work as follows:<br /> </p> <pre>class IssuesController < ApplicationController<br /> def index<br /> ...<br /> respond_to do |format|<br /> format.html # will render index.rhtml<br /> format.js { render :layout => false }<br /> # the above line will render index.rhtml but without the layout<br /> end<br /> end<br /> ...<br />end <br /></pre> <p> The above lines made our controller ready to respond to normal or AJAX requests (given that AJAX requests will have the .js format). In the former case it will return back the whole page but in the latter it will omit rendering the layout and only send the content.<br /> </p><p> Ok, but what we still need two views. I hear you, and fear not, you will have to change nothing. Actually it's only a trivia to adapt your views to this model. Let's see how this can be done.<br /> </p>Here's a normal view code sample, and pardon me, I won't use the link_to helper method for clarity purposes:<br /><br /> <pre>...<br /><div id=”content”><br />...<br /><ul><br /> <li><a href=”url1”>Link1</a></li><br /> <li><a href=”url2”>Link2</a></li><br /> <li><a href=”url3”>Link3</a></li><br /></ul><br />...<br /><form target=”url4”><br /> ...<br /> <input type=”submit”><br /></form><br />...<br /></div><br />... <br /></pre> <p> The above fragment shows a list of links and a form. All should behave in the normal way and reload the page when clicked. Now let's imagine that the user is using a Javascript capable browser. What effect could this coming fragment have on his experience?<br /> </p> <pre><br /><!-- Warning, this fragment requires prototype.js --><br /><script><br /> function ajaxifyLinks(){<br /> // check if there is AJAX support<br /> if(!Ajax.getTransport())return false;<br /> // loop on all links<br /> $$('a').each(function(link){<br /> // attach an event observer to each link's 'onclick' event<br /> Event.observe(link, 'click', function(event){<br /> // call the original url (with .js added) with AJAX<br /> new Ajax.Updater('content',link.href+”.js”);<br /> // stop the browser from following the link<br /> return false;<br /> });<br /> });<br /> // loop on all forms<br /> $$('form').each(function(form){<br /> // attach an event observer to each form's 'onsubmit' event<br /> Event.observe(form, 'submit', function(event){<br /> // send the form contents via AJAX<br /> new Ajax.Updater('content',form.action+”.js”,<br /> {params:Form.serialize(form),<br /> method:'post'});<br /> // stop the browser from submitting the form<br /> return false; <br /> });<br /> });<br /> } <br /></script> <br /> </pre><p> The above code will transform EVERY link and form in the page to AJAX, that is, in case that the browser supports both Javascript and AJAX. Otherwise links and forms will remain untouched and they will behave as usual.<br /> </p> <p>Of course this is a minimalistic example. We knowingly avoided touching on any special case but, in another installment of this article we will get more intimate with the subject and may be we can handle more aggressive ... techniques!</p>oldmoehttp://www.blogger.com/profile/14341721253106429644noreply@blogger.com2tag:blogger.com,1999:blog-2858328690300381570.post-44124971417339719282007-07-22T12:57:00.000-07:002007-07-22T12:59:57.052-07:00Zimbra, violating Open Source termsNot all pretenders are Open source... This is true for zimbra at least which claims it is open source, but actually I see everythg they r doing is against open source. check <a href="http://blogs.zdnet.com/BTL/index.php?p=3430">this</a> for detailed discussion abt zimbra as open source.<br />I am still in my battle field working on Zimbra.<br />We upgraded to the new zimbra version now....<br />In this new version I found sthg in the code that made my nerves; all variables are written in this format "_158", "_140".<br />I found this hilarious...Ahmed Abd-ElHaffiez Husseinhttp://www.blogger.com/profile/09563341584184001660noreply@blogger.com7tag:blogger.com,1999:blog-2858328690300381570.post-48226100736281596882007-07-17T12:58:00.000-07:002007-08-27T02:04:00.014-07:00Java vs. C++ - Part Two<span style="font-family:trebuchet ms;">These are </span><strong style="font-family: trebuchet ms;">some more</strong><span style="font-family:trebuchet ms;"> differences between Java and C++.</span><div style="font-size: 100%; font-family: 'Trebuchet MS',Trebuchet,Verdana,Sans-Serif;"> <table style="border-style: inset; border-collapse: collapse;" border="3" cellpadding="10" width="100%"> <tbody> <tr><th style="width: 10%;"><br /></th><th style="width: 45%;">Java</th><th style="width: 45%;">C++</th></tr> <tr> <th>Class attributes and behaviors</th> <td>Attributes are "instance variables".<br />Behaviors are "methods"</td> <td>Attributes are "data members".<br />Behaviors are "member functions"</td> </tr> <tr> <th>Extending Class Object</th> <td>Every class is a subclass of Object and so inherits the 11 methods defined by class object, you never create a class from scratch. Even if a class doesn't explicitly use <span style="color: rgb(0, 0, 204);font-family:monospace;font-size:100%;" >extends</span> in its definition, it implicitly extends Object</td> <td>You can create classes from scratch. A class will inherit attributes and behaviors of a base class ONLY when its declaration explicitly implies that it should.</td> </tr> <tr> <th>Packages</th> <td>Every class belongs to a package even if not explicitly specified it will be the default package ( the current directory )</td> <td>Classes do not have packages. Their containing header files are simply included in source files in which they are to be used</td> </tr> <tr> <th>Constructor name</th> <td>Methods other than the constructor of a class ARE ALLOWED to have the same name as the class AND to specify return types but these are not constructors and won't be called when an object is created.</td> <td>It is NOT ALLOWED for any member function other than the constructor to have the same name as the class name AND it is INVALID to specify a return type for any constructor.</td> </tr> <tr> <th>Initializing attributes</th> <td>Instance variables CAN be initialized where they are declared IN THE CLASS BODY, by the class's constructor, or they can be assigned values by "set" methods. Instance variables that are not explicitly initialized by the programmer are initialized by the compiler (primitive numeric variables are set to 0, booleans are set to false and references are set to null).</td> <td>Data members can be initialized ONLY by the class's constructor, or they can be assigned values by "set" methods. Instance variables that are not explicitly initialized by the programmer are NOT automatically initialized (they will have whatever values that happened to be stored in their allocated memory space).</td> </tr> <tr> <th>Accessing hidden attributes</th> <td>An instance variable hidden by a local variable (having the same name) can be accessed in a method by:<pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);">this.variableName</pre>(this is a reference to the current object)</td> <td>Such a hidden data member can be accessed in the member function by:<pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);">ClassName::variableName<br />or<br />this->variableName</pre>(this here is a pointer to the current object)</td> </tr> <tr> <th>Access modifiers</th> <td>Each instance variable or method declaration in a Class definition must be preceded by an access modifier.</td> <td>Access modifiers are followed by a colon and apply to all following member declarations until overridden by another access modifier. If they were omitted they are implicitly applied by the compiler:<br />for classes: members are private by default.<br />for structs: members are public by default.</td> </tr> <tr> <th>Package access</th> <td>Members that have no access modifier preceding their declaration are accessible to all the classes included in the same package.</td> <td>Members are either public or private and the only way that another class could access a non-public member of a different class is by inheritance of protected members or by being declared as a friend class of that class.</td> </tr> <tr> <th>Memory leaks</th> <td>Are less likely to occur because Java performs automatic garbage collection to help return memory back to the system. When an object is no longer used in a program ( there are no references to the object e.g. if null was assigned to the objects reference ) it is marked for garbage collection. Before the garbage collector returns memory resources to the system it calls the finalize method of the object to be destroyed.</td> <td>Are common because memory is not automatically reclaimed to the system it is the programmer's responsibility to do that himself by freeing the memory in the Class destructor when its task is over.</td> </tr> <tr> <th>Multiple inheritance</th> <td>Is not supported but interfaces are supported that allow a class to acquire multiple functionalities from any number of interfaces</td> <td>Is supported.</td> </tr> <tr> <th>Over-ridden superclass methods</th> <td>Can be accessed from the subclass by:<pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);">super.methodName();</pre></td> <td>Such an over-ridden base-class member function can be accessed by the derived class by:<pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);">BaseClassName::functionName();</pre></td> </tr> <tr> <th>Calling superclass constructor</th> <td>To explicitly call the superclass Parent constructor from the subclass Child constructor:<pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);">public Child( int a, int b )<br />{<br /> super( a );<br /> x = b;<br />}<br /></pre>The calling statement must be the first statement in the subclass constructor</td> <td>To do the same thing here it goes like this:<pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);">Child( int a, int b )<br /> : Parent( a )<br />{<br /> x = b;<br />}</pre>here we use the member initializer ( : ) to call the Parent constructor before the body of the constructor is executed</td> </tr> <tr> <th>Polymorphism and dynamic binding</th> <td>Applies automatically.<br />When a reference to a subclass object is assigned to a superclass reference which is then used to invoke a superclass method that is overridden in the subclass definition the java compiler only checks that the class of the reference really has that method and the java interpreter calls the method of the actual data type of the object at execution time.</td> <td>Does NOT apply automatically.<br />When a pointer to a derived-class object is assigned to a base-class pointer which is then used to invoke a base-class member function that is overridden in the derived class definition the compiler treats the object exactly as an object of the base-class and the base-class member function is called for the object. This is overcome by declaring the function to be a vertual one and in this case the compiler generates code that would at run time access the appropriate version of the function for the actual object's data type.</td> </tr> <tr> <th><span style=";font-family:monospace;font-size:100%;" >final</span> methods and <span style=";font-family:monospace;font-size:100%;" >final</span> classes</th> <td><p>A method that is declared <span style="color: rgb(0, 0, 204);font-family:monospace;font-size:100%;" >final</span> cannot be overridden in a subclass.</p><p>A class that is declared <span style="color: rgb(0, 0, 204);font-family:monospace;font-size:100%;" >final</span> cannot be a superclass( cannot have subclasses).</p></td> <td>Does not have an equivalent in C++</td> </tr> <tr> <th><span style=";font-family:monospace;font-size:100%;" >const</span> functions</th> <td>Java has no equivalent for C++'s <span style="color: rgb(0, 0, 204);font-family:monospace;font-size:100%;" >const</span> functions</td> <td>A member function can be declared as <span style="color: rgb(0, 0, 204);font-family:monospace;font-size:100%;" >const</span>, indicating that calling that member function does not change the object.</td> </tr> <tr> <th>Abstract classes</th> <td>Are declared by using <span style="color: rgb(0, 0, 204);font-family:monospace;font-size:100%;" >abstract</span> and have one or more abstract mehtods<pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);">public abstract ClassName {<br /> private int instanceVariable;<br /> public int someMethod1()....<br /> public void someMethod2()...<br /> public abstract int method(); <br /> //abstract method<br />}</pre></td> <td>Must have one or more pure virtual functions <pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);">class ClassName {<br />public:<br /> virtual int someFunction1()...<br /> virtual int someFunction2()...<br /> virtual int function() = 0;<br /> // pure virtual funtion<br />private:<br /> int dataMember;<br /> ...<br />};</pre></td> </tr> <tr> <th>GUI support</th> <td>Normally has packages that support frames, windows, Graphical User Interface components.</td> <td>Does not normally support them. Appropriate third party libraries must be obtained to offer their support.</td> </tr> </tbody> </table> </div>mshalabyhttp://www.blogger.com/profile/13133192118777632030noreply@blogger.com0tag:blogger.com,1999:blog-2858328690300381570.post-6834991223997182842007-06-30T13:41:00.000-07:002007-07-05T06:18:38.045-07:00The fall of MS fanFor most of life, I have been a Microsoft user. I wasn't a MS' fan. But I didn't find it not so bad working on Window, and it was fair enough for me, although it is not perfect.<br /><br />I had great passion to try the Vista out, the long delayed version, 6 years or sthg. We all read abt it for many years, and how much it will be sthg fascinating and a new..bla..bla..bla<br />When I tried it on my PC, i was expecting sthg that could dazzle me.<br /><br />finally, I got Vista business. I was totally wrong, I regret the day i installed Vista.<br /><br />well, it is beautiful, the 3-D desktop switcher looks nice.<br />I faced many problems with Drivers. the problem is not that they r not verified by Vista. the problem that from time to time, I had to redefine the drivers.<br />my network card kept to be disconnected. I couldn't stay online for couple of hours. the stupid thing that when it disconnects, i have to press by myself "diagnose and repair" then should press "get a new IP" to ask the Vista to get another IP. What is this stupidity!!! didn't I define that already in the connection properties!! the answer to that question is the "<a href="http://www.youtube.com/watch?v=VKM1cAtAdtQ">ALLOW</a>" :))<br />If u run sthg on vista, and precipitate away from ur PC, don't expect it is working.<br /><br />u should wait because u will have to answer "Continue with getting a new IP?", "continue with opening this executable file"..etc I really hate this stupid thg in vista. i don't think i have to press 3 clickes just to run exe file..<br /><br />The gadgets are terrible, I have never turned them on. they are not innovative and poor.<br /><br />fighting to have a network connection really annoyed me.<br />this Vista eats the processor and the Memory. it slows down ur PC. without any tasks running ur RAM usage can be 512 MB. to use a PC now, u have to add $X to buy extra RAM for the Vista and $Y extra to more powerful processor, don't forget that u will pay for the Vista too :)<br />Vista price is too high. despite the license price is the almost the same since many old versions of windows, it is too high comparing with HW costs these days. Windows license can exceed 20% of ur costs!!!!<br /><br />the only thg that may keep windows alive is that majority of mobile tools need windows to sync, and some softwares are not still available for MACs.<br /><br />anyway, I didn't like the Vista thg.<br />Not friendly, no performance, no stability...nothing.Ahmed Abd-ElHaffiez Husseinhttp://www.blogger.com/profile/09563341584184001660noreply@blogger.com2tag:blogger.com,1999:blog-2858328690300381570.post-51067999387446247732007-06-28T11:08:00.000-07:002007-06-30T01:19:17.920-07:00Improve your Company using Workflow System<span style="font-family:verdana;">Work flow,</span><br /><span style="font-family:verdana;">Business Process Management,</span><br /><span style="font-family:verdana;">Business Process Modeling,</span><br /><span style="font-family:verdana;">Methodologies,</span><br /><span style="font-family:verdana;">Work Procedures</span><br /><br /><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;font-family:verdana;">All these related words can come together to build an understandable vision of the workflow system.</p> <p class="MsoNormal" face="verdana" style="text-align: left; direction: ltr; unicode-bidi: embed;">The Business Process is a group of logically related tasks that come together to form a methodology to implement work procedures.<br />So companies try to automate these procedures using a workflow system to gain its benefits.</p><p class="MsoNormal" face="verdana" style="text-align: left; direction: ltr; unicode-bidi: embed;"> </p><p class="MsoNormal" face="verdana" style="text-align: left; direction: ltr; unicode-bidi: embed;">You can find more about workflow <a href="http://en.wikipedia.org/wiki/Workflow">here</a>.</p><p class="MsoNormal" face="verdana" style="text-align: left; direction: ltr; unicode-bidi: embed;"> </p> <p class="MsoNormal" face="verdana" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style="font-weight: bold; font-style: italic; color: rgb(0, 0, 153);">So why do we need workflow system?</span><br />Some of the benefits we can get by using workflow can be briefed by the following</p><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed; font-family: verdana;"> </p> <ul style="font-family:verdana;"><li><!--[if !supportLists]--><span style=""><span style="font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; font-size-adjust: none; font-stretch: normal;font-size:7;" > </span></span><!--[endif]--><span dir="ltr" style="font-size:100%;"><b>Improved efficiency</b></span><span style="font-size:100%;"> - automation of many business processes results in the elimination of many unnecessary steps</span></li></ul><ul style="font-family:verdana;"><li><!--[if !supportLists]--><!--[endif]--><span dir="ltr" style="font-size:100%;"><b>Better process control</b></span><span style="font-size:100%;"> - improved management of business processes achieved through standardizing working methods and the availability of audit trails </span></li></ul> <ul style="font-family:verdana;"><li><!--[if !supportLists]--><span style="font-size:100%;"><span style="font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; font-size-adjust: none; font-stretch: normal;"> </span></span><!--[endif]--><span dir="ltr" style="font-size:100%;"><b>Improved customer service</b></span><span style="font-size:100%;"> – consistency in the processes leads to greater predictability in levels of response to customers </span></li></ul> <ul style="font-family:verdana;"><li><!--[if !supportLists]--><!--[endif]--><span dir="ltr" style="font-size:100%;"><b>Flexibility</b></span><span style="font-size:100%;"> – software control over processes enables their re-design in line with changing business needs </span></li></ul> <ul style="font-family:verdana;"><li><!--[if !supportLists]--><!--[endif]--><span dir="ltr" style="font-size:100%;"><b>Business process improvement</b></span><span style="font-size:100%;"> - focus on business processes leads to their streamlining and simplification</span></li></ul> <p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed; color: rgb(0, 0, 153); font-weight: bold; font-style: italic; font-family: verdana;">How to implement a workflow system for our company?</p><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed; color: rgb(0, 0, 153); font-weight: bold; font-style: italic;"> </p><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed; font-family: verdana;">Well, Thanks god we didn't have to pay for a license to build a system using <a href="http://msdn2.microsoft.com/en-us/netframework/aa663328.aspx">Microsoft workflow foundation</a>.</p><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed; font-family: verdana;"> </p><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;">We have <a href="http://www.jboss.com/products/jbpm"><b>JBPM</b></a> (Java Business process management)<b> </b>which is a flexible, extensible workflow management system build on Java and it is an Open source project.</p> <p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;">A lot of open source projects are developed like (<a href="http://java-source.net/open-source/workflow-engines/open-business-engine">Open Business Engine</a> <a href="http://java-source.net/open-source/workflow-engines/the-open-for-business-workflow-engine">The Open for Business Workflow Engine</a> <a href="http://java-source.net/open-source/workflow-engines/openwfe">OpenWFE</a> <a href="http://java-source.net/open-source/workflow-engines/wfmopen">WfMOpen</a> <a href="http://java-source.net/open-source/workflow-engines/xflow">XFlow</a> <a href="http://java-source.net/open-source/workflow-engines/micro-flow">Micro-Flow</a> <a href="http://java-source.net/open-source/workflow-engines/jflower">JFlower</a> <a href="http://java-source.net/open-source/workflow-engines/yawl">YAWL</a> <a href="http://java-source.net/open-source/workflow-engines/zebra">Zebra</a> <a href="http://java-source.net/open-source/workflow-engines/apache-agila">Apache Agila</a> <a href="http://java-source.net/open-source/workflow-engines/antflow">Antflow</a> <a href="http://java-source.net/open-source/workflow-engines/beexee">Beexee</a> <a href="http://java-source.net/open-source/workflow-engines/dalma">Dalma</a> <a href="http://java-source.net/open-source/workflow-engines/swish">Swish</a> etc...)</p><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"></p> <p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;">I believe that <a href="http://sourceforge.net/projects/runawfe">RunaWFE</a> is one of the best.<br /><br />RUNA WFE is an environment for JBoss jBPM workflow engine.<span dir="rtl" lang="AR-SA"><o:p></o:p></span><br />It is a cross-platform end user solution for business process development and execution.<span dir="rtl" lang="AR-SA"><o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"> </p> <p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;">Together RUNA WFE and JBoss jBPM provide an easy to use business process management system.<br /><br /><span style="font-size:100%;"><b><i><span style="font-family:Verdana;">RUNA WFE provides:</span></i></b></span></p><ul><li><span style=";font-family:Verdana;font-size:100%;" >an end user GUI to define business processes without any coding: draw flowcharts, define roles and variables, lay out forms</span></li><li><span style=";font-family:Verdana;font-size:100%;" >an end user GUI to load and execute processes</span></li><li><span style=";font-family:Verdana;font-size:100%;" >an administrative interface to create and remove users/groups and grant rights</span></li><li><span style=";font-family:Verdana;font-size:100%;" >a possibility of writing automatic "bots" that can participate in business processes</span></li><li><span style=";font-family:Verdana;font-size:100%;" >a possibility to code new GUI elements, variable types, organizational structure functions etc. that extend existing RUNA WFE components and will be available to end users through the GUI</span></li></ul> <p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"> </p><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed; font-weight: bold;"><span style="font-size:130%;">Then How to integrate our workflow system with other software?</span></p><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed; font-weight: bold;"> </p><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><b><i><span style="color: rgb(51, 51, 255);">Integrating RunaWFE with MySQL Database:</span></i></b></p><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"> </p><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;">Simply, do the following steps:</p> <ol><li><span style=";font-family:Verdana;font-size:100%;" >Add The File mysqldb-ds.xml to your jboss deploy folder "</span><span style=";font-family:Verdana;font-size:100%;" >server\default\deploy</span><span style=";font-family:Verdana;font-size:100%;" >".</span><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiV-WF3nOZE0AOF-EKKnHZnMlVdrkBYol6EycndBAx2zso9zPLG9fJaK4l90Fgd-a3ZNhyphenhyphenqMy3Nr75KBBgNrhtFkwFI8bu_t1qEsPuA8fs54AZoSUtsRvX1OteSWiYIZClURAmdW7w7m0M/s1600-h/xml.PNG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiV-WF3nOZE0AOF-EKKnHZnMlVdrkBYol6EycndBAx2zso9zPLG9fJaK4l90Fgd-a3ZNhyphenhyphenqMy3Nr75KBBgNrhtFkwFI8bu_t1qEsPuA8fs54AZoSUtsRvX1OteSWiYIZClURAmdW7w7m0M/s400/xml.PNG" alt="" id="BLOGGER_PHOTO_ID_5081172552444715938" border="0" /></a></li></ol><ol start="2"><li><span style="">In server\default\conf\hibernate.cfg.xml Change</span></li></ol> <p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"></p><pre style="border: 1px dotted black; padding: 6px; background-color: rgb(255, 255, 204);font-size:12px;color:black;">connection.datasource = java:/MYSQLDS<span dir="rtl" lang="AR-SA"><o:p></o:p></span><br />Dialect = net.sf.hibernate.dialect.MySQLDialect </pre><p></p> <ol start="3"><li><span style=";font-family:Verdana;font-size:100%;" >Important Note : Don't forget to add "com.mysql.jdbc.Driver" to your l</span><span style=";font-family:Verdana;font-size:100%;" >ibrary </span><span style=";font-family:Verdana;font-size:100%;" >This is done by adding "mysql-connector-java-3.1.14.jar" to the lib Folder.</span></li></ol> <p class="MsoNormal" style="margin-left: 0.25in; text-align: left; direction: ltr; unicode-bidi: embed;"><span style=";font-family:Verdana;font-size:100%;" ><o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><b><i><span style="color: rgb(51, 51, 255);">Integrating RunaWFE with LDAP:</span><o:p></o:p></i></b></p> <p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed; color: rgb(0, 0, 153); font-weight: bold; font-style: italic;"> </p><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;">Unfortunately integrating RunaWFE with LDAP can be done to a certain level, </p> <p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;">In any workflow system you have to define your users, their groups and also their permissions and Roles.</p> <p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;">So you can authenticate through LDAP but you still has to add your ldap users in your workflow system so you can define their groups and Roles.</p> <p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><o:p></o:p>So what we will do now is to authenticate using our LDAP and also import our LDAP users into RunaWFE to manage their groups, Permissions and Roles.<br /><br />Fortunately RunaWFE helps us in doing both the importing and the authentication.</p><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"> </p><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;">To Add LDAP Authentication To RunaWFE Do the Following:</p> <ol style="margin-top: 0in;" start="1" type="1"><li class="MsoNormal" style="margin-right: 0in; margin-left: 0.5in; text-align: left; direction: ltr; unicode-bidi: embed;">Add the LDAPPasswordLoginModule to src\af\logic\ru\runa\af\authentication </li></ol><pre style="border: 1px dotted black; padding: 6px; background-color: rgb(255, 255, 204);font-size:12px;color:black;"><span style="font-size:100%;"><b>public</b></span><span style=""> </span><span style="font-size:100%;"><b><span style="">boolean</span></b></span><span style=""> login() </span><span style="font-size:100%;"><b><span style="">throws</span></b></span><span style=""> LoginException {</span><span style=""><o:p></o:p></span><span style="font-size:100%;"> </span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="font-size:100%;"><i><span style="">SERVER_URL</span></i></span><span style="">= LDAPImporterResources.<i>getServerURL</i>();</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="font-size:100%;"><b><span style="">if</span></b></span><span style=""> (</span><span style="">callbackHandler</span><span style=""> == </span><span style="font-size:100%;"><b><span style="">null</span></b></span><span style="">)</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="font-size:100%;"><b><span style=""><span style="font-family:monospace;">t</span>hrow</span></b></span><span style=""> </span><span style="font-size:100%;"><b><span style="">new</span></b></span><span style=""> LoginException(</span><span style="">"No CallbackHandler provided."</span><span style="">);</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span>Callback[] callbacks = </span><span style="font-size:100%;"><b><span style="">new</span></b></span><span style=""> Callback[2];</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"> </span><span style=""><span style=""> </span>callbacks[0] = </span><span style="font-size:100%;"><b><span style="">new</span></b></span><span style=""> NameCallback(</span><span style="">"actor name: "</span><span style="">);</span><span style=""><o:p></o:p></span><span style="font-size:100%;"> </span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span>callbacks[1] = </span><span style="font-size:100%;"><b><span style="">new</span></b></span><span style=""> PasswordCallback(</span><span style="">"password: "</span><span style="">, </span><span style="font-size:100%;"><b><span style="">false</span></b></span><span style="">);</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span>ExecutorDAO executorDAO = </span><span style="font-size:100%;"><b><span style="">null</span></b></span><span style="">;</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="font-size:100%;"><b><span style="">try</span></b></span><span style=""> {</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="">callbackHandler</span><span style="">.handle(callbacks);</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span>String actorName = ((NameCallback) callbacks[0]).getName();</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="font-size:100%;"><b><span style="">if</span></b></span><span style=""> (actorName == </span><span style="font-size:100%;"><b><span style="">null</span></b></span><span style="">)</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="font-size:100%;"><b><span style="">throw</span></b></span><span style=""> </span><span style="font-size:100%;"><b><span style="">new</span></b></span><span style=""> LoginException(</span><span style="">"No actor name was provided."</span><span style="">);</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="font-size:100%;"><b><span style="">char</span></b></span><span style="">[] tmpPasswordChars = ((PasswordCallback) callbacks[1]).getPassword();</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="font-size:100%;"><b><span style="">if</span></b></span><span style=""> ((tmpPasswordChars == </span><span style="font-size:100%;"><b><span style="">null</span></b></span><span style="">) || (tmpPasswordChars.</span><span style="">length</span><span style=""> == 0))</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="font-size:100%;"><b><span style="">throw</span></b></span><span style=""> </span><span style="font-size:100%;"><b><span style="">new</span></b></span><span style=""> LoginException(</span><span style="">"No password was provided."</span><span style="">);</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span>String password = </span><span style="font-size:100%;"><b><span style="">new</span></b></span><span style=""> String(tmpPasswordChars);</span><span style=""><o:p></o:p></span> </p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="">env</span><span style="">.put(Context.</span><span style="font-size:100%;"><i><span style="">INITIAL_CONTEXT_FACTORY</span></i></span><span style="">,<br /></span></p><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"> <span style="">"com.sun.jndi.ldap.LdapCtxFactory"</span><span style="">);<span style=""> </span></span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="">env</span><span style="">.put(Context.</span><span style="font-size:100%;"><i><span style="">PROVIDER_URL</span></i></span><span style="">, </span><span style="font-size:100%;"><i><span style="">SERVER_URL</span></i></span><span style="">);<span style=""> </span></span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="">env</span><span style="">.put(Context.</span><span style="font-size:100%;"><i><span style="">SECURITY_AUTHENTICATION</span></i></span><span style="">, </span><span style="">"simple"</span><span style="">);<span style=""> </span></span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="">env</span><span style="">.put(Context.</span><span style="font-size:100%;"><i><span style="">SECURITY_PRINCIPAL</span></i></span><span style="">, </span><span style="">"uid="</span><span style="">+ actorName +</span></p><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""> ",ou=people,"</span><span style="">+ LDAPImporterResources.<i>getDC</i>()); </span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="">env</span><span style="">.put(Context.</span><span style="font-size:100%;"><i><span style="">SECURITY_CREDENTIALS</span></i></span><span style="">, password);<span style=""> </span></span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span>DirContext ctx = </span><span style="font-size:100%;"><b><span style="">new</span></b></span><span style=""> InitialDirContext(</span><span style="">env</span><span style="">);</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span>ctx.close(); </span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span>executorDAO = DAOFactory.<i>getInstance</i>().createExecutorDAO();</span><span style=""><o:p></o:p></span><span style="font-size:100%;"><br /></span></p><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style="font-family:mon;"> </span><span style="">actor</span><span style=""> = executorDAO.<s>getActorCaseInsensitive</s>(actorName);</span><span style=""><o:p></o:p></span> </p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="">succeeded</span><span style=""> = </span><span style="font-size:100%;"><b><span style="">true</span></b></span><span style="">;</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="font-size:100%;"><b><span style="">return</span></b></span><span style=""> </span><span style="">succeeded</span><span style="">;</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span>} </span><span style="font-size:100%;"><b><span style="">catch</span></b></span><span style=""> (IOException e) {</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="font-size:100%;"><b><span style="">throw</span></b></span><span style=""> </span><span style="font-size:100%;"><b><span style="">new</span></b></span><span style=""> LoginException(e.toString());</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span>} </span><span style="font-size:100%;"><b><span style="">catch</span></b></span><span style=""> (UnsupportedCallbackException e) {</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="font-size:100%;"><b><span style="">throw</span></b></span><span style=""> </span><span style="font-size:100%;"><b><span style="">new</span></b></span><span style=""> LoginException(e.getMessage());</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span>} </span><span style="font-size:100%;"><b><span style="">catch</span></b></span><span style=""> (NamingException e) {</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="font-size:100%;"><b><span style="">throw</span></b></span><span style=""> </span><span style="font-size:100%;"><b><span style="">new</span></b></span><span style=""> LoginException(e.getMessage());</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span>} </span><span style="font-size:100%;"><b><span style="">catch</span></b></span><span style=""> (InternalApplicationException e) {</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="font-size:100%;"><b><span style="">throw</span></b></span><span style=""> </span><span style="font-size:100%;"><b><span style="">new</span></b></span><span style=""> LoginException(e.getMessage());</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span>} </span><span style="font-size:100%;"><b><span style="">catch</span></b></span><span style=""> (ExecutorOutOfDateException e) {</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="font-size:100%;"><b><span style="">throw</span></b></span><span style=""> </span><span style="font-size:100%;"><b><span style="">new</span></b></span><span style=""> LoginException(e.getMessage());</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span>} </span><span style="font-size:100%;"><b><span style="">catch</span></b></span><span style=""> (RuntimeException e) {</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="font-size:100%;"><b><span style="">throw</span></b></span><span style=""> </span><span style="font-size:100%;"><b><span style="">new</span></b></span><span style=""> LoginException(e.getMessage());</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span>} </span><span style="font-size:100%;"><b><span style="">finally</span></b></span><span style=""> {</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span></span><span style="font-size:100%;"><b><span style="">try</span></b></span><span style=""> {</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span>DAOHelper.<i>close</i>(executorDAO, </span><span style="font-size:100%;"><b><span style="">true</span></b></span><span style="">);</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span>} </span><span style="font-size:100%;"><b><span style="">catch</span></b></span><span style=""> (InternalApplicationException e) {</span><span style=""><o:p></o:p></span></p><span style="font-size:100%;"> </span><span style=""><span style=""> </span></span><span style="font-size:100%;"><b><span style="">throw</span></b></span><span style=""> </span><span style="font-size:100%;"><b><span style="">new</span></b></span><span style=""> LoginException(e.getMessage());</span><span style=""><o:p></o:p></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span>}</span><span style=""><o:p></o:p></span> </p><span style="font-size:100%;"></span><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style=""><span style=""> </span>}</span><span style=""><o:p></o:p></span><span style=""><br /></span></p><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style="">}</span><br /></p></pre> <ol style="margin-top: 0in;" start="2" type="1"><li class="MsoNormal" style="margin-right: 0in; margin-left: 0.5in; text-align: left; direction: ltr; unicode-bidi: embed;">Modify the LDAP importer Configuration File ldap-importer.properties in server/conf to point to your LDAP server.</li><li class="MsoNormal" style="margin-right: 0in; margin-left: 0.5in; text-align: left; direction: ltr; unicode-bidi: embed;">Change login-module.properties in server/conf to the LDAPPasswordLoginModule.</li></ol> <pre style="border: 1px dotted black; padding: 6px; background-color: rgb(255, 255, 204); font-size: 12px; color: black;"><p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;"><span style="">#ru.runa.af.authenticaion.NTLMLoginModule=SUFFICIENT</span><span style=""><o:p></o:p></span><span style="font-size:100%;"><br /></span><span style="">#ru.runa.af.authenticaion.InternalDBPasswordLoginModule=SUFFICIENT</span><span style=""><o:p></o:p></span><span style="font-size:100%;"><br /></span><span style="">#ru.runa.af.authenticaion.ADPasswordLoginModule=SUFFICIENT</span><span style=""><o:p></o:p></span><span style="font-size:100%;"><br /></span><span style="">#ru.runa.af.authenticaion.KerberosLoginModule=SUFFICIENT</span><span style=""><o:p></o:p></span><span style="font-size:100%;"><br /><u><span style="">ru.runa.af.authenticaion.LDAPPasswordLoginModule</span></u></span><span style="">=</span><span style="">SUFFICIENT</span><span style=""><o:p></o:p></span></p></pre> <ol style="margin-top: 0in;" start="4" type="1"><li class="MsoNormal" style="margin-right: 0in; margin-left: 0.5in; text-align: left; direction: ltr; unicode-bidi: embed;"><span style="">You have to modify some constant variable in class LDAPImporter</span><span style=""> </span><span style="">to accommodate with your LDAP settings.</span></li></ol><span style="font-size:100%;"><b><span style=""><pre size="12px" color="black" style="border: 1px dotted black; padding: 6px; background-color: rgb(255, 255, 204);"><span style="font-weight: normal;">private</span><span style="font-weight: normal;"> static final String <i>OBJECT_CLASS_ATTR_USER_VALUE</i> = "user";<br /></span><span style="font-weight: normal;font-size:100%;" ><span style="">private</span></span><span style=""><span style="font-size:100%;"><span style="font-weight: normal;"> </span>static final<span style="font-weight: normal;"> String </span><i style="font-weight: normal;">DISPLAY_NAME</i><span style="font-weight: normal;"> = "name";</span><br /></span></span></pre></span></b><span style=""></span></span><ol style="margin-top: 0in;" start="5" type="1"><li class="MsoNormal" style="margin-right: 0in; margin-left: 0.5in; text-align: left; direction: ltr; unicode-bidi: embed;">Run the LDAP importer Tool which will import your users to the ldap users group in the Executors list of Runa.</li><li class="MsoNormal" style="margin-right: 0in; margin-left: 0.5in; text-align: left; direction: ltr; unicode-bidi: embed;"><span style="">If you changed the Administrator login password don't forget to change it in the LDAPimporter script.</span></li></ol> <p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;">Finally to create your own processes you can use the <a href="http://sourceforge.net/forum/forum.php?forum_id=710360">Graphical Process Designer</a><span style=""> </span>which helps design your processes in a very simple way.<br /><o:p></o:p></p> <p class="MsoNormal" style="text-align: left; direction: ltr; unicode-bidi: embed;">Enjoy your Automated Workflow System and your process improvement.</p>ABDOOOOhttp://www.blogger.com/profile/06497826312654732518noreply@blogger.com0tag:blogger.com,1999:blog-2858328690300381570.post-79460612990964357562007-06-28T10:11:00.000-07:002007-07-04T06:12:01.756-07:00Java vs. C++ - Part OneThese are <strong>only</strong> some of the differences between Java and C++ that I found so far that drew my attention and I think are worth mentioning.<div style="font-size: 100%; font-family: 'Trebuchet MS',Trebuchet,Verdana,Sans-Serif;"> <table style="border-style: inset; border-collapse: collapse;" border="3" cellpadding="10" width="100%"> <tbody> <tr><th style="width: 10%;"><br /></th><th style="width: 45%;">Java</th><th style="width: 45%;">C++</th></tr> <tr><th>Compiling source code</th><td>When we compile a source file a .class file is generated in java byte-codes ( machine independent = portability ) that is not translated into machine language instructions until in the run time when interpreted by the Java Virtual Machine<br />( machine dependent ).</td><td>A source file is compiled and linked to produce an .exe file in machine language that is ready to be executed when the file is loaded into memory and run by the operating system.</td></tr> <tr><th>Function definitions </th><td>All function definitions and variable declarations are inside Classes even main(). Nothing is allowed to be outside a class except imports and package names.</td><td>Function definitions are outside class definitions. They have prototypes whose place decides function scope</td></tr> <tr><th>Including classes</th><td>Importing a package.* just directs the compiler to the location of classes used in the code so that only these classes are included not the whole package. </td><td>while in C++ I think that including a header file means that all classes in that header file will be compiled and linked to the source file.</td></tr> <tr><th>Ending class definitions</th><td>Class definitions end with } without a semicolon.</td><td>Class definitions end with };</td></tr> <tr><th>Creating objects</th><td>All objects must be created with <span style="color: rgb(0, 0, 204);font-family:monospace;font-size:100%;" >new</span>, so they are all dynamically allocated in the heap.<br />Only primitive data types can be allocated on the stack.</td><td>Objects can also be created and allocated without <span style="color: rgb(0, 0, 204);font-family:monospace;font-size:100%;" >new</span> so they are put on the stack in the scope of their declaration.</td></tr> <tr><th>Declaring a reference:</th><td>Declaring a reference to an object without using <span style="color: rgb(0, 0, 204);font-family:monospace;font-size:100%;" >new</span> to allocate the object only reserves space for the reference and no object is created in memory until <span style="color: rgb(0, 0, 204);font-family:monospace;font-size:100%;" >new</span> is used and the resulting object is given to the reference to point to it.</td><td>Declaring an object without initializing it makes the compiler call the default constructor for the object's class and memory is allocated for the object in the stack.</td></tr> <tr><th>Calling static methods</th><td><span style="color: rgb(0, 0, 204);font-family:monospace;font-size:100%;" >ClassName.methodName( args.. );</span></td><td><span style="color: rgb(0, 0, 204);font-family:monospace;font-size:100%;" >ClassName::functionName( args.. );</span><br />or <span style="color: rgb(0, 0, 204);font-family:monospace;font-size:100%;" >ObjectName.functionName( args..);</span></td></tr> <tr><th>Wrapper classes</th><td>Java has wrapper classes for primitive data types that contains static methods for handling them<br />e.g.<span style="color: rgb(0, 0, 204);font-family:monospace;font-size:100%;" > String string = Integer.toString( intVariable );</span></td><td>C++ doesn't normally have them in its standard libraries</td></tr> <tr><th>Array declaration and memory allocation:</th><td>An array is considered an object that has to be allocated by new.<br /><pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);"> int c[];<br /></pre> <p>declares the array reference</p> <pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);"> c = new int[ 12 ];<br /></pre> <p>allocates the array and automatically initialize its elements to zero for numeric primitive types, false for boolean, null for references ( non-primitive types)<br />or</p> <pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);"> int c[] = new int[ 12 ];<br />// in one step<br /></pre><p>you can never specify the number of elements in the [] in a declaration unlike C++.</p> <p>For multiple array declarations:</p> <pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);"> double a[], b[]; <br /><br />a = new double[ 100 ];<br />b = new double[ 27 ];<br /><br />or<br /><br />double a[] = new double[ 100 ],<br />b[] = new double[ 27 ];<br />or<br />double[] a, b; <br /><br />a = new double[ 100 ];<br />b = new double[ 27 ];<br /><br />or<br /><br />double[] a = new double[ 100 ],<br /> b = new double[ 27 ];<br /></pre> <p>Elements of an array of a primitive data type contain values of that data type.<br />While elements of an array of a non-primitive data type contian "references" to objects of that data type.<br /></p><p>( they have the value null by default )<br /></p> <p>Allocating and initializing arrays in declarations:</p> <pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);"> int n[] = { 32, 27, 64, 18, 95,<br /> 14, 90, 70, 60, 37 };<br />// initializer list<br /></pre><p>Array size is determined by the number of elements in the list. Here <span style="color: rgb(0, 0, 204);font-family:monospace;font-size:100%;" >new</span> operator is provided by the compiler and the array object is also dynamically allocated.</p> <p>When a Java program is executed. the Java interpreter checks array element subscripts to be sure they are valid. If there is an invalid subscript, Java generates an exception: <strong>ArrayIndexOutOfBoundsException</strong>.</p></td><td><pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);"> int c[ 12 ];<br /></pre><p>declares and allocated memory for 12 int elements without initializing them also memory is not dynamically allocated but instead it is preserved from the start and is allocated in the stack I presume.<br />For multiple array declaration:</p> <pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);"> double a[ 100 ],<br /> b[ 27 ];<br /></pre> <p>Elements of an array of any data type contain values or objects of that data type.<br />Objects for which an array can be declared must have a default constructor to be called for every element when the array is declared.</p><p>initializing arrays in declarations:</p> <pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);"> int n[ 10 ] = { 0 };<br /></pre><p>initialize elements of array n to 0</p> <pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);"> int n[] = { 1, 2, 3, 4, 5 };<br /></pre> <p>array size determined by the number of elements in the list </p> <p>No checking for array bounds is done by the compiler so the programmer must be very carful not to exceed the array length</p></td></tr> <tr><th>Multiple subscripted arrays</th><td><p>Doesn't directly support multiple-subscripted arrays but allows the programmer to specify single-subscripted arrays whose elements are also single-subscripted arrays, achieving the same effect.<br />i.e. arrays of arrays: </p> <pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);"> int b[][] = { { 1, 2 },<br /> { 3, 4, 5 } };<br /></pre><p>b[ 0 ] is a reference to an array of 2 elements<br />b[ 1 ] is a reference to an array of 3 elements </p> <pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);"> int b[][];<br />b = new int[ 3 ][ 3 ];<br /></pre> <p>3 by 3 array allocated</p> <pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);"> int b[][];<br />b = new int[ 2 ][];<br /></pre><p>allocates rows</p> <pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);"> b[ 0 ] = new int[ 5 ];<br /></pre><p> allocates columns for row 0 </p> <pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);"> b[ 1 ] = new int[ 3 ];<br /></pre><p>allocates columns for row 1 </p></td><td><p>Directly supports multiple-subscripted arrays and their elements are placed consecutively in memory row after row and the elements are actually located by pointer arithmetic. </p> <pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);"> int b[][] = { { 1, 2 },<br /> { 3, 4, 5 } };<br /></pre><p>causes an error in C++ "error: declaration of 'b' as multidimensional array must have bounds for all dimensions except the first."<br /></p> <pre style="font-family: monospace; font-size: 100%; color: rgb(0, 0, 204);"> int b[][ 3 ] = { { 1, 2 },<br /> { 3, 4, 5 } };<br /></pre> <p>declares and preserves memory for a 2 by 3 multidimensional array b and initializes missing element in the list b[ 0 ][ 2 ] by 0. </p></td></tr> <tr><th>Passing arguments</th><td><p>Java does not allow the programmer to decide whether to pass an argument call-by-value or call-by-reference:<br /> Primitive data type variables are always passed call-by-value.<br />Objects are not passed to methods; references to objects are passed<br />(call-by-value just like pointers in C++ are) so the method can manipulate the object directly.</p></td><td><p>You can pass primitive data types or objects either call-by-value or call-by-reference ( using pointers or references to them ).</p></td></tr> <tr><th>Returns</th><td><p>When returning information from a method via a return statement:</p> <p>Primitive data type variables are always returned by value (a copy is returned).<br />Objects are always returned by reference - a reference to the object is returned.</p></td><td><p>Objects and primitive data type variables can be returned by value or by reference</p></td></tr> <tr><th>Constant variables</th><td><p>Constant variables ( read only variables ) are declared using <span style="color: rgb(0, 0, 204);font-family:monospace;font-size:100%;" >final</span>. </p> </td><td><p>They are declared using <span style="color: rgb(0, 0, 204);font-family:monospace;font-size:100%;" >const</span>.</p></td></tr> </tbody> </table> </div>mshalabyhttp://www.blogger.com/profile/13133192118777632030noreply@blogger.com0tag:blogger.com,1999:blog-2858328690300381570.post-11651159211790457322007-06-19T14:30:00.000-07:002007-06-19T14:31:11.249-07:00Erlang Vs Object OrientedI think that in the future the functional programming community will be at peak. currently I think that the functional communities are too small to beat the Java community.<br /><br />the functional is easier to any person. any one can write a functional code. Erlang for example has a light VM that can make profit of multiprocessors availability. this doesn't depend on certain compiler that enables parallelism in Java or C.<br />if you don't care about performance, think about parallelism as simpler way to structure software in a domain where there is a lot of natural concurrency.<br /><br />I read a paper "Structured Programming Using Processes" in which the author tried to prove that the Erlang was capable to support a personal accounting software application. Maybe you can take a look to it later.<br /><br />also, I like to point to <a href="http://yaws.hyber.org/">Yaws</a>, Yaws is a HTTP high performance 1.1 webserver particularly well suited for dynamic-content webapplications. I ma really amazed by its performance.<br /><br />well, but why Erlang is not widely used till now?<br />Well the world likes Java. the type safe language. Security in distributed Erlang is “all or nothing,” so when a node is authenticated to another, it can perform any operation.<br />process isolation is not complete, a process can flood another process with messages, or it can steal all the CPU cycles by entering into an infinite loop.Ahmed Abd-ElHaffiez Husseinhttp://www.blogger.com/profile/09563341584184001660noreply@blogger.com0tag:blogger.com,1999:blog-2858328690300381570.post-70407398287425252122007-05-25T07:45:00.000-07:002007-05-25T07:49:44.552-07:00Using action+client caching to speed up your Rails applicationToo many visitors are visiting your website and loads of dynamic data are being delivered to your clients?. Of those visitors, you have more people reading your site's content than people modifying it? meaning, you get lots more GET requests than POST, PUT or DELETE?<br /><br />If the above questions are all answered with a YES, then, my friend, you are desperately in need of caching. Caching will help you lessen the load on your servers by doing two main things:<br /><ol><li>It eliminates lengthy trips to the (slow by nature) database to fetch the dynamic data<br /></li><li>It frees precious CPU cycles needed in processing this data and preparing it for presentation.</li></ol>I have faced the same situation with a project we are planning, we are bound to have much more GETS than any other HTTP command, and since we are building a Restful application we will have a one to one mapping between our web resources (<span class="blsp-spelling-error" id="SPELLING_ERROR_0">urls</span>) and our application models. The needs of our caching mechanism are the following:<br /><ol><li>It needs to be fast<br /></li><li>It needs to be shared across multiple servers<br /></li><li>Authentication is required for some actions</li><li>Page presentation changes (slightly) based on logged in user</li><li>Most pages are shared and only a few are private for each user<br /></li></ol>We have two answer the following now, what caching technique and what cache store we will use?<br /><br />The cache store part is easy, <span class="blsp-spelling-error" id="SPELLING_ERROR_1">memcached</span> seems like the most sensible choice as it achieves points 1 & 2 and is orthogonal to the other 3 requirements. So it is <span class="blsp-spelling-error" id="SPELLING_ERROR_2">memcached</span> for now.<br /><br />Now, which caching technique?. Rails has several caching methods, the most famous of those is Page, Action and Fragment Caching. Greg Pollack has a great writeup on these <a href="http://www.railsenvy.com/2007/2/28/rails-caching-tutorial">here</a> and <a href="http://www.railsenvy.com/2007/3/20/ruby-on-rails-caching-tutorial-part-2">here</a>. Model caching is also an option, but it can get a bit too complicated, so I'm leaving it out for now, it can be implemented later though (layering your caches is usually a good idea)<br /><br />Page caching is the fastest, but we will use the ability to authenticate (unless we do so via HTTP authentication, which I would love to, but sadly is not the case). This leaves us with action and fragment caching. Since the page contains slightly different presentation based on the logged in user (like a hello message and may be a localized <span class="blsp-spelling-error" id="SPELLING_ERROR_3">datetime</span> string) fragment caching would sound to be the better choice, no? Well, I would love to be able to use action caching after all, this way I can server whole pages without invoking the <span class="blsp-spelling-error" id="SPELLING_ERROR_4">renderer</span> at all and really avoid doing lots of string processing by Ruby.<br /><br /><br />There is a solution, if you'd just wake up and smell the coffee, we are in Web 2.0 and we should think in Web 2.0 age solutions for Web 2.0 problems. What if add little JavaScript to the page that dynamically displays the desired content based on user role. And if the content is really little, why not store it in a session cookie? Max Dunn implements a similar solution for his wiki <a href="http://blog.maxdunn.com/articles/2006/09/16/ruby-on-rails-advanced-page-caching">here</a> and thus the page is served the same with <span class="blsp-spelling-error" id="SPELLING_ERROR_5">dom</span> manipulation kicking in to do the simple mods for this specific user. Rendering of those is done on the client so no load on the server, and since the mods are really small, the client is not hurt either, and it gets to get the page much faster, it's a win win situation. Life can't be better!<br /><br />No, It can!. In a content driven website, many people check a hot topic frequently, and many reread the same data they read before. In those cases, the server is sending those a cached page yes, but it is resending the same bits which the browser has in it's cache. This is a waste of bandwidth, and your mongrel will be waiting for the page transfer to finish before it can consume another request.<br /><br />A better solution is to utilize client caching. Tell the browser to use the version in its cache if it is not invalidated. Just send the new data in a cookie and and let the page dynamically modify itself to adapt to the logged in user. Relying on session cookies for dynamic parts will prevent the browser from displaying stale data between two different session. But the page itself will not be fetched over the wire more than once, even for different users on the same computer.<br /><br />I am using the <a href="http://blog.craz8.com/action-cache-plugin/">Action Cache <span class="blsp-spelling-error" id="SPELLING_ERROR_6">Plugin</span></a> by Tom Fakes to add client caching capabilities to my Action Caches. Basically things go in the following manner:<br /><ol><li>A GET request is encountered and is intercepted<br /></li><li>Caching headers are checked, if none exists then proceed<br />else send (304 NOT MODIFIED)<br /></li><li>Action Cache is checked if it is not there then proceed<br />else send the cached page (200 OK)<br /></li><li>Action processed and page content is rendered</li><li>Page added to cache, with last-modified header information</li><li>Response sent back to browser (200 OK + all headers)</li></ol>So how to determine the impact of applying these to the application<br /><ol><li>We need to know the percentage of GET requests, which can be cached as opposed to POST, PUT and DELETE ones<br /></li><li>Of those GET requests, how many are repeated?</li><li>Of those repeated GET requests, how many originate from the same client?</li></ol>Those numbers can tell us if our caching model works fine or not, this should be the topic of the next installment of this article<br /><br />Happy cachingoldmoehttp://www.blogger.com/profile/14341721253106429644noreply@blogger.com1tag:blogger.com,1999:blog-2858328690300381570.post-61920530825370719902007-05-24T14:54:00.000-07:002007-05-24T16:17:10.535-07:00Agile ProcessMy first reading about <a href="http://en.wikipedia.org/wiki/Agile_software_development">Agile</a> was the <a href="http://agilemanifesto.org/principles.html">Agile Manifesto</a>. I think this was enough to get the whole picture of the agile philosophy.<br /><div style="text-align: justify;">I really don't recommend that you get a book to read about the agility; it will be a contradiction to read a book as long as the Agile methods emphasize working software as the primary measure of progress. It is better you spend the time understanding your working environment and maturity to apply the best process that can fit with it.<br /></div>I lived a similar experience with <a href="http://www.espace.com.eg/">eSpace</a> when they were aiming to get a <a href="http://www.sei.cmu.edu/cmm/">CMM</a> certificate, <a href="http://www.sei.cmu.edu/cmmi/">CMMI</a> or whatever they will call it after couple of years.<br /><div style="text-align: justify;">I think that finally the people here got the good decision by putting this plan away, and put their own standards, the standards best fitting with their teams and their environment. I doubt their was a need to some white collar guy to supervise our documents and our working styles to decide whether we fit to Mr XYZ standards or not. I also got the chance to meet some guys from another company having this certificate. What I found is that they modified their hierarchical structure just to accommodate the standard although their team wasn't capable at all to support this hierarchy.<br /></div><br />Anyway, let's move to another point...<br /><div style="text-align: justify;">When we talk about the agile process we should identify very well any possible limitations before adopting it. It is very clear for me that it needs mature people, and this can be considered as one of the limitations.<br /></div><div style="text-align: justify;">Another factor that may limit the agile adoption is the "<span style="font-weight: bold;">distributed software</span>". Lately all our projects are distributed. Customers are from Europe, USA, Gulf. Developers are working remotely from different areas.<br /></div>What are the challenges behind such distributed agile work???<br /><br /><div style="text-align: justify;">The answer of this question can be summarized in knowing that agile methods mainly rely on informal processes to facilitate coordination while distributed software development typically relies on formal mechanisms.<br /></div><br /><span style="font-weight: bold;">Challenges in Agile Distributed Development<br /></span><ol><li style="text-align: justify;"><span style="font-style: italic;">Communication need vs. communication impedance</span>: How can we achieve a balance in formality of communication in agile distributed environments?</li><li style="text-align: justify;"><span style="font-style: italic;">Fixed vs. evolving quality requirements: </span>the Agile relies on ongoing negotiations between the developer and the customer while Distributed Development often relies on fixed, upfront commitments on quality requirements.</li><li style="text-align: justify;"><span style="font-style: italic;">People- vs. process-oriented control: </span>We appreciate the people-orientation the most.</li><li style="text-align: justify;"><span style="font-style: italic;">Lack of cohesion:</span> Generally speaking about the distributed environment, people may feel In distributed development, participants are less likely to perceive themselves as part of the same team when compared to co-located participants. the agile adds some more excitement to it :)</li></ol><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyXHo4wgbYzYlBq5Zmn7eHCR3yJ1LdXx-ivSB40s-254prcDlk08uBhq-dFN-uUm202DPWK2h8w45FAFuoGVGAu5nakVZteWelRWqzytueX2_dmkscm-N3AbPzWeAk79j8iXeJs2zi-i_W/s1600-h/challenges.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyXHo4wgbYzYlBq5Zmn7eHCR3yJ1LdXx-ivSB40s-254prcDlk08uBhq-dFN-uUm202DPWK2h8w45FAFuoGVGAu5nakVZteWelRWqzytueX2_dmkscm-N3AbPzWeAk79j8iXeJs2zi-i_W/s400/challenges.jpg" alt="" id="BLOGGER_PHOTO_ID_5068249661237512834" border="0" /></a><br /><span style="font-weight: bold;">Practices<br /></span><ol><li style="text-align: justify;"><span style="font-style: italic;">Process Refactor</span>: Continuous process adjustments instead of following strictly the agile practices. It is also recommended to document the requirements at different levels of formality.</li><li style="text-align: justify;"><span style="font-style: italic;">Knowledge Spreading:</span> the team should share their knowledge regarding different domains(business, code, test cases..etc). Alot of tools were developed to reduce the overhead of knowledge-sharing activities. Code/process Repository is a must. the <a href="http://en.wikipedia.org/wiki/Wiki">Wiki</a> also is a very important way to share the How-Tos between members. I can't neglect the <a href="http://en.wikipedia.org/wiki/Bugzilla">Bugzilla</a> with its role in creating database to help teams report issues and assign priorities.</li><li style="text-align: justify;"><span style="font-style: italic;">Short Iterations:</span> any iteration should not exceed 2 weeks. short iterations help to detect any misunderstandings for the project business and prevent any time waste.</li><li style="text-align: justify;"><span style="font-style: italic;">Start with well-understood functionalities:</span> In order to create the best atmosphere for developers there should be a solid sand to start to be familiar with the processes, tools, and the application. this can be some kind different that the agile which advocates the development of features prioritized as critical by the customer.</li><li style="text-align: justify;"><span style="font-style: italic;">Improve Communication:</span> Synchronized work hours are very important for the team. Also try to make the informal communication be done through formal channels. for example, let it through the emails so that it can be archived. In the distributed Projects it is recommended that the project leader/manager should be involved in the communication and the synchronization process than the Agile practice. finally, some daily mechanisms should be done to maintain minimal communication like morning online meeting.<br /></li><li><span style="font-style: italic;">Building Trust:</span> trust involves both the team and the customers.</li></ol><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8FXLIi5CqJucnb6c_uYS9GPLNCxqAVqBaQlmtrL6H828zpDKElzDVKOFlOw4Lan954N6Xp7nDC0LkkNUGMKsVUe3Wv3pB_8n_wnIttEhZWvnPSMR0QNmNmCL4O5YV47RmIJ8RT6FPdnA3/s1600-h/practices.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8FXLIi5CqJucnb6c_uYS9GPLNCxqAVqBaQlmtrL6H828zpDKElzDVKOFlOw4Lan954N6Xp7nDC0LkkNUGMKsVUe3Wv3pB_8n_wnIttEhZWvnPSMR0QNmNmCL4O5YV47RmIJ8RT6FPdnA3/s400/practices.jpg" alt="" id="BLOGGER_PHOTO_ID_5068249326230063730" border="0" /></a><br /><span style="font-size:85%;"><span style="font-weight: bold;">References: </span><br />1. Ebert, C. and Neve, P.D. Surviving global software development. IEEE Software 18, 2 (Mar./Apr. 2001), 62–69.<br />2. Highsmith, J. and Cockburn, A. Agile software development: The business of innovation. IEEE Computer 34, 9 (Sept. 2001), 120–122.<br />3. Matloff, N. Offshoring: What can go wrong? IT Professional (July/Aug.2005), 39–45.</span>Ahmed Abd-ElHaffiez Husseinhttp://www.blogger.com/profile/09563341584184001660noreply@blogger.com0tag:blogger.com,1999:blog-2858328690300381570.post-87975844844435331152007-05-23T21:30:00.000-07:002007-05-24T09:58:16.898-07:00Virtual functions in C++<font style="" face="times new roman" size="3"><br /></font><blockquote face="times new roman"><font size="3"> "In order to implement the concept of </font><font style="font-style: italic; font-weight: bold;" size="3">Polymorphism</font><font size="3"> which is a corner-stone of OOP the C++ compiler has to find a way to make it possible."</font></blockquote><font style="" face="times new roman" size="3"><br /><br />Lets see how the story begins.<br /><br />Derived classes inherit member functions of the base class but when some member functions are not exactly appropriate for the derived class they should provide their own version of these functions to override the immediate base class' functions and make their own objects happy. So if any of these functions is called for a derived object the compiler calls its class' version of that function.<br /><br />This works quite fine when the types of objects are known at compile time so that the compiler knows which function to call for each particular object. The compiler knows where to find the copy of the function for each class and so the addresses used for these function calls are </font> <font style="font-style: italic; font-weight: bold;" face="times new roman" size="3">settled</font><font style="" face="times new roman" size="3"> at compile time. ( </font><font style="font-weight: bold;" face="times new roman" size="3">static binding</font><font style="" face="times new roman" size="3"> )<br /><br />Suppose that we have a lot of derived objects at different levels of the inheritance hierarchy that have a common base class and that they need to be instantiated at run time. Here the compiler does not know in advance what derived class objects to expect. These objects would be dynamically allocated and the code for handling these objects should be able to deal with all them.<br /><br />It is perfectly legitimate to use base class pointers to point to these objects but that requires the compiler to handle them exactly the same way they would handle their base class objects. So they would call base class versions of member functions and none of the member functions specific for the derived class would be accessible.<br /><br />To solve this problem </font><font style="font-weight: bold; font-style: italic;" face="times new roman" size="3">Virtual functions</font><font style="" face="times new roman" size="3"> are used to allow </font><font style="font-style: italic; font-weight: bold;" face="times new roman" size="3">dynamic binding</font><font style="" face="times new roman" size="3">.<br /><br /></font><blockquote face="times new roman"><font size="3"> "...It seems that our friend, the compiler of course, is very resourceful."</font></blockquote><font style="" face="times new roman" size="3"><br /><br />To support Polymorphism at runtime the compiler builds at compile time </font><font style="font-weight: bold; font-style: italic;" face="times new roman" size="3">virtual function tables</font><font style="" face="times new roman" size="3"> ( </font><font style="font-weight: bold;" face="times new roman" size="3">vtables</font><font style="" face="times new roman" size="3"> ). Each class with one or more virtual functions has a vtable that contains pointers to the appropriate virtual functions to be called for objects of that class. Each object of a class with virtual functions contains a pointer to the vtable for that class which is usually placed at the beginning of the object.<br /><br />The compiler then generates code that will:<br /><br /> 1. dereference the base class pointer to access the derived class object.<br /> 2. dereference its vtable pointer to access its class vtable.<br /> 3. add the appropriate offset to the vtable pointer to reach the desired function pointer.<br /> 4. dereference the function pointer to execute the appropriate function.<br /><br />This allows dynamic binding as the call to a virtual function will be </font><font style="font-style: italic;" face="times new roman" size="3">routed</font><font style="" face="times new roman" size="3"> at run time to the virtual function version appropriate for the class.<br /><br />Impressive isn't it?<br /><br />Well that made me try just for fun to write code that would do these steps instead of the compiler.<br /><br />But as I did this another question evolved.<br /><br /><font style="font-weight: bold;">How does member functions get their "this" pointer ?</font> ( pointer to the object the function is called for )<br /><br />I know that the compiler should implicitly pass 'this' as an argument to the member function so that it can use it to access data of the object it is called for.<br /><br />I used in my example a single virtual function that takes no arguments and returns void.<br />So at first I tried calling the destination virtual function with no arguments. The function was called already but the results showed it has used some false value for 'this' that pointed it somewhere other than the object and gave the wrong results.<br /><br />So I tried calling the function and passing it the pointer to the object and it seemingly worked just fine.<br /><br />Here's the code I tried...<br /></font><pre style="color: blue; background: white; margins: 5px; padding: 5px;"><span style="font-size:85%;"><br /><br />#include <iostream><br /><br />using std::cout;<br />using std::endl;<br /><br />class Parent {<br />public:<br /> Parent( int = 0, int = 0 ); // default constructor<br /> void setxy( int, int );<br /> int getx() const { return x; }<br /> int gety() const { return y; }<br /> virtual void print();<br />private:<br /> int x;<br /> int y;<br />};<br /><br />Parent::Parent( int a, int b )<br />{<br /> setxy( a, b );<br />}<br /><br />void Parent::setxy( int a, int b )<br />{<br /> x = ( a >= 0 ? a : 0 );<br /> y = ( b >= 0 ? b : 0 );<br />}<br /><br />void Parent::print()<br />{<br /> cout << " [ x: " << x << ", y: " << y << "] ";<br />}<br /><br />class Child : public Parent {<br />public:<br /> Child( int a = 0, int b = 0, int c = 0 , int d = 0 );<br /> void setzt( int c, int d );<br /> int getz() const { return z; }<br /> int gett() const { return t; }<br /> virtual void print();<br />private:<br /> int z;<br /> int t;<br />};<br /><br />Child::Child( int a, int b, int c, int d )<br /> : Parent( a, b )<br />{<br /> setzt( c, d );<br />}<br /><br />void Child::setzt( int c, int d )<br />{<br /> z = ( c >= 0 ? c : 0 );<br /> t = ( d >= 0 ? d : 0 );<br />}<br /><br />void Child::print()<br />{<br /> Parent::print();<br /> cout << " [ z: " << z << ", t: " << t << "] ";<br />}<br /><br />class GrandChild : public Child {<br />public:<br /> GrandChild( int = 0, int = 0, int = 0, int = 0, int = 0);<br /> void sete( int );<br /> int gete() const { return e; }<br /> virtual void print();<br />private:<br /> int e;<br />};<br /><br />GrandChild::GrandChild( int a, int b, int c, int d, int e )<br /> : Child( a, b, c, d )<br />{<br /> sete( e );<br />}<br /><br />void GrandChild::sete( int num )<br />{<br /> e = ( num >= 0 ? num : 0 );<br />}<br /><br />void GrandChild::print()<br />{<br /> Child::print();<br /> cout << " [ e: " << e << " ]";<br />}<br /><br />int main()<br />{<br /> Parent parentObj( 7, 8 );<br /> Child childObj( 56, 23, 6, 12 );<br /> GrandChild grandchildObj( 4, 64, 34, 98, 39 );<br /> <br /> // declare an array of pointers to Parent<br /> <br /> Parent *parentPtr[ 3 ]; <br /><br /> cout << "size of Parent = " << sizeof( Parent ) << " bytes\n";<br /> cout << "size of Child = " << sizeof( Child ) << " bytes\n";<br /> cout << "size of GrandChild = "<br /> << sizeof( GrandChild ) << " bytes\n";<br /><br /><br /> parentPtr[ 0 ] = &parentObj; // direct assignment<br /> parentPtr[ 1 ] = &childObj; // implicit casting<br /> parentPtr[ 2 ] = &grandchildObj; // implicit casting<br /><br /> cout << "\nThe Derived objects accessed by"<br /> " an array of pointers to Parent:\n\n";<br /><br /> for ( int i = 0; i < 3; i++ ) {<br /> cout << "Object " << i + 1 << " : ";<br /> cout << "\tvtable ptr (" << *( ( void ** ) parentPtr[ i ] ) << ")\n" ;<br /> // vtable ptr at the beginning of the object<br /> <br /> // initialize pointer to function<br /> <br /> void (* funptr ) ( Parent * ) = NULL; <br /><br /> // assign to it pointer to function in vtable<br /> <br /> funptr = *( *( ( void (*** ) ( Parent * ) ) parentPtr[ i ] ) );<br /> <br /> cout << "\t\tpointer 1 in vtable is (" << ( void * ) funptr<br /> << ")\n\t\t( pointer to virtual function 1 'print()' )";<br /><br /> cout << "\n\n\t\tdata: ";<br /><br /> funptr( parentPtr[ i ] ); // call the 1st function in vtable<br /> // and passing ( this ) to it<br /> // without using parentPtr[ i ]->print();<br /> cout << "\n" << endl;<br /> }<br /><br /> return 0;<br />}<br /><br /><br /></span></pre><span style="font-size:85%;">The output should look like this:<br/><br /><pre style="background: black; color: white; margins: 5px; padding: 20px;" width="75%"><br />size of Parent = 12 bytes<br />size of Child = 20 bytes<br />size of GrandChild = 24 bytes<br /><br />The Derived objects accessed by an array of pointers to Parent:<br /><br />Object 1 : vtable ptr (0043FD90)<br /> pointer 1 in vtable is (00401480)<br /> ( pointer to virtual function 1 'print()' )<br /><br /> data: [ x: 7, y: 8]<br /><br />Object 2 : vtable ptr (0043FD80)<br /> pointer 1 in vtable is (004015B8)<br /> ( pointer to virtual function 1 'print()' )<br /><br /> data: [ x: 56, y: 23] [ z: 6, t: 12]<br /><br />Object 3 : vtable ptr (0043FD70)<br /> pointer 1 in vtable is (004016E6)<br /> ( pointer to virtual function 1 'print()' )<br /><br /> data: [ x: 4, y: 64] [ z: 34, t: 98] [ e: 39 ]<br /></pre><br /><br /><font style="" face="times new roman" size="3"><font size="2"><br /></font>In order to reach the function pointer to the desired function ( print() ) the parentPtr of the object which normally points to its beginning had to be casted to type pointer to pointer to pointer to function before it was dereferenced to give the vtabel pointer and then dereferenced again to give the first pointer to function in the vtable.<br /><br /> Polymorphism uses virtual functions in another interesting way. Virtual functions enables us to create special classes for which we never intend to instantiate any objects. These classes are called <font style="font-weight: bold; font-style: italic;">abstract classes</font> and they only used to provide an appropriate base class that passes a common interface and/or implementation to their derived classes.<br /><br />Abstract classes are not specific enough to define objects. <font style="font-style: italic; font-weight: bold;">Concrete classes</font> on the other hand have the specifics needed to have a real object. To make a base class abstract it must have one or more <font style="font-style: italic; font-weight: bold;">pure virtual functions</font> which are those having = 0 added at the end of its function prototype.<br /><br /> virtual void draw() const = 0;<br /><br />These pure virtual functions should be all overridden in the derived classes for these to be concrete ones or else they would be abstract classes too.<br /><br />Suppose we have a base class Hardware. We can never draw, print the production date or price unless we know the exact type of hardware we're talking about. So it looks that class Hardware could make a good example for an abstract base class.<br /><br />Another example could be class Furniture and it might look something like this:<br /><br /></font><pre style="color: blue; background: white; margins: 5px; padding: 5px;"><span style="font-size:85%;"><br />Class Furniture {<br />public:<br /> ...<br /> virtual double getVolume() const = 0; // a pure virtual<br /> function<br /> virtual void draw() const = 0; // another one here<br /> ... <br />}<br /></pre><font style="" face="times new roman" size="3"><br />Here class Furniture definition contains only the interface and implementation to be inherited.<br />It even does not contain any data members.<br /><br />That's it.<br />Hope you liked this article.<br /><br />I will be happy to receive your comments.</font>mshalabyhttp://www.blogger.com/profile/13133192118777632030noreply@blogger.com1tag:blogger.com,1999:blog-2858328690300381570.post-81477793340418599472007-05-23T02:36:00.000-07:002007-05-23T02:56:00.352-07:00Bullet Proof code using RegExp.Regular expressions is a great way to find those hard to find strings.<br />Suppose you have a bunch of old code and you want to bullet proof it or you might be interested in auditing it and for starters you want to find those uninitialized variables using eclipse.<br /><br />the pattern of uninitialized variable could be in the following format<br /><br />(Var)(space or more)(Alphanumeric word)(Possible space or more)(semi-colon)<br /><br /><br />to search for (space or more) we use expression<br />(\s+)<br />\s means space<br />+ means one or more<br /><br />to search for(Alphanumeric word) we use expression<br />(\w+)<br />\w means Alphanumeric character<br />+ means one or more<br /><br />to search for (Possible space or more) we use expression<br />(\s*)<br />\s means space<br />* means zero or more<br /><br />so the regular expression would be int(\s+\w+\s*); it will return all uninitialized ints.<br /><br />It would be great if we collect those regular expressions and keep them in a library to be our arsenal towards bad code.<br /><br />do u have more regular expressions to share?Hamdy K.http://www.blogger.com/profile/16477230220844362817noreply@blogger.com4tag:blogger.com,1999:blog-2858328690300381570.post-23458504738971183932007-05-22T05:52:00.000-07:002007-05-22T06:01:31.476-07:00Ruby on Rails, web development that doesn't h...<object height="350" width="425"><br /><param value="http://www.youtube.com/v/H868NSM2yAg" name="movie"><br /><param value="transparent" name="wmode"><br /><embed wmode="transparent" type="application/x-shockwave-flash" src="http://www.youtube.com/v/H868NSM2yAg" height="350" width="425"></embed><br /></object>Hatem Mahmoudhttp://www.blogger.com/profile/16852317264499407161noreply@blogger.com1tag:blogger.com,1999:blog-2858328690300381570.post-71007145162054479122007-05-21T01:51:00.001-07:002007-05-21T02:07:02.946-07:00Test Mail ServerYou are on delivery, you need to test your application, and you need to make sure it sends email notification when the form is filled.. you look around wondering were did the system admin go.. and after a while when you catch him sitting in the buffet, and ask him for a mail server to test your logic, he stares at you for a while before replying " We got no mail server for testing". Well, at this point the degree of frustration reaches its peak, and you start wondering why in the world do we hire those sys admins?<br /><br />well you won't need them anymore, just use Gmail, yes you can use your gmail account (sure you have one).. here is the configuration<br /><br />address => "smtp.gmail.com",<br />port => 587,<br />domain => "yourdomain.com",<br />authentication => :plain,<br />user_name => "yourgmailaccount",<br />password => "yourgmailpassword"Samer El Sahnhttp://www.blogger.com/profile/07314985878394159062noreply@blogger.com1tag:blogger.com,1999:blog-2858328690300381570.post-1466481068961766272007-05-18T04:37:00.000-07:002007-05-19T13:16:26.355-07:00MogileFS revisitedSo i got this reply on my <a href="http://espaceblogs.blogspot.com/2007/05/mogilefs-storage-engine.html">recent post</a><br /><br /><span style="font-style: italic;">"Please recall that MogileFS has no POSIX file API. All file transfers</span><br /><span style="font-style: italic;">are done via HTTP. So, it really isn't a drop-in replacement for NFS</span><br /><span style="font-style: italic;">or any other network file system. You need to add logic to your</span><br /><span style="font-style: italic;">application to deal with MogileFS.</span><br /><br /><span style="font-style: italic;">Also, you can't do updates to a file; you must overwrite the entire</span><br /><span style="font-style: italic;">file if you make any changes.</span><br /><br /><span style="font-style: italic;">MogileFS is primarily intended for a write-once/read-many setup."</span><br /><br />So how would this fit in our system, for a starter I think it won't be of much impact, since we are storing system images. The idea of updating files won't be an issue, as images intend to be very large, and once stored it is either replaced by a newer image or used to restore a system. Also we are going to use Ruby on Rails to interface with the <a href="http://wiki.systemimager.org/index.php/Main_Page">system Imager</a>, our ope source imaging system, and ruby has a plugin for MogilrFS, so it won't be a problem to integrate it, and everything seems ok.<br /><br />What about other systems, how could be MogileFS useful in other systems.. Would these issues be a problem for application in need for a smart storage? Lets take a Mail system for example, we have multiple servers serving a domain, and users' mail boxes are spread among these servers, The file in this case will be the emails, and since we need no update on the emails, write once/read many condition will be fulfilled. Although if the mail service was not tailored made or customized, it will be hard to integrate MogileFS, meaning if you are using a ready made Mail server like Sendmail or Qmail, you will find difficulties to make MogileFS your storage engine.<br /><br />As a conclusion MogileFS is better used with applications that are developed with MogileFS as its storage engine in mind. Although you can use it with out of the box systems, it won't be smooth ride, but fr sure there are some systems which will not benefit from MogileFS like file sharing or workflow systems.<br />Still I can't wait to try it over, and keeping you updated.Samer El Sahnhttp://www.blogger.com/profile/07314985878394159062noreply@blogger.comtag:blogger.com,1999:blog-2858328690300381570.post-73384276247052210672007-05-17T08:27:00.000-07:002007-05-19T07:42:00.562-07:00Hi, I'm Ruby on Rails - Part 1What do you get when you cross the Mac vs PC commercials and <a href="http://www.railsenvy.com/">Rails Envy</a>? Ruby on Rails ads to get everyone hyped for Railsconf, that's what!<br /><object height="350" width="425"><br /><param value="http://www.youtube.com/v/PQbuyKUaKFo" name="movie"><br /><param value="transparent" name="wmode"><br /><embed wmode="transparent" type="application/x-shockwave-flash" src="http://www.youtube.com/v/PQbuyKUaKFo" height="350" width="425"></embed><br /></object>Hatem Mahmoudhttp://www.blogger.com/profile/16852317264499407161noreply@blogger.com3tag:blogger.com,1999:blog-2858328690300381570.post-34337620052463526272007-05-17T04:37:00.000-07:002007-05-19T07:46:13.115-07:00Update a newly added column in a migrationOne of the very interesting features I like about <a href="http://www.rubyonrails.com/">Rails</a> is migrations. It is a version control system that keeps track of all database changes. You can easily move your database to any previous version with its schema and data.<br /><br />During my last project, I have tried to create a migration that adds a column to a table and then updates that column.<br /><pre>def self.up<br /> add_column :file_types, :mime_type, :string<br /> q = FileType.find_by_name('quicktime')<br /> q.update_attributes :mime_type => 'video/quicktime'<br />end</pre>If you run that migration, the new column would be added successfully but no data would be updated. Why is that ?!<br /><br />The problem is that you are trying to update the column, mime_type, immediately after adding it and before allowing the model, FileType, to detect the new changes (strange, I know, but true).<br /><br />The solution, <a href="http://api.rubyonrails.org/classes/ActiveRecord/Migration.html">as documented</a>, is simple. You just need to call<br /><span style="font-weight: bold;">reset_column_information</span> to ensure that the model has the latest column data before the update process.<br /><br />Here is the code modified:<br /><pre>def self.up<br /> add_column :file_types, :mime_type, :string<br /> q = FileType.find_by_name('quicktime')<br /><span style="font-weight: bold;"> FileType.reset_column_information</span><br /> q.update_attributes :mime_type => 'video/quicktime'<br />end</pre>And here is the code of <span style="font-weight: bold;">reset_column_information</span><pre>def reset_column_information<br /> read_methods.each { |name| undef_method(name) }<br /> @column_names = @columns = @columns_hash = @content_columns = @dynamic_methods_hash = @read_methods = @inheritance_column = nil<br />end</pre>It simply resets all the cached information about columns, which will cause them to be reloaded on the next request.<br /><br />Although this problem has a solution, a really worse problem should be mentioned here. In the first case, when you don't call <span style="font-weight: bold;">reset_column_information</span>, you don't get any error! The column simply doesn't update. Additionally, if you go back to the previous version and then re-run the migration, surprise, you get no problems and the column updates successfully!<br /><br />I don't know if this is a reported bug, but it is a strange behavior. However, this won't prevent me from developing more and more Rails applications.Hatem Mahmoudhttp://www.blogger.com/profile/16852317264499407161noreply@blogger.com1tag:blogger.com,1999:blog-2858328690300381570.post-57389128896634334532007-05-16T09:46:00.000-07:002007-05-16T10:04:04.020-07:00MogileFS Storage engine!<p class="MsoNormal">I came across <a href="http://danga.com/mogilefs/">this</a> today, It seemed interesting.. MogileFS is intended for storage hungry applications, its all about spreading your files across cheap devices on different hosts, something like RAID+NFS+DataReplication.<br /><br />The Idea is very nice and simple, you have multiple servers, and every server has multiple devices, you sum up all these storage units into one big storage, you have a tracker application that you consult when reading or writing to this huge storage, and the tracker take responsibility of saving your data and making sure that your data is available even if multiple hosts went off line. <br /> <!--[if !supportLineBreakNewLine]--><br /> <!--[endif]--></p> <p class="MsoNormal">This application just came in time, we just had an idea of a project that takes images from your server and store it on a network storage, so if something wrong happens to your server you can simply take this image and restore it back to <span style=""> </span>your server, or you can even restore this image on a different server to clone it, or something like that. The challenge was where to store all of these images. By doing a simple calculation, if you have 100 users and every user has a 10 G.B. image, then you are bound to maintain a tera of storage.. and scalability will be an issue.</p> <p class="MsoNormal"><o:p> </o:p></p> <p class="MsoNormal">With MogileFS you will gain three advantages here, one, you will have cheap disks on cheap servers with your storage distributed on it. Two, you will gain from this distribution by installing the application on all of these servers, and so gaining high availability. Three, scaling will be as simple as adding a server to this farm. So with about half the price of a SAN and its expensive disks, you will get high availability for your storage and application. Ofcourse we will have to manage this distributed environment. One of the ways to tackle it is to create no slave architecture, all servers are masters, and every server can detect on which server the user’s image is stored by consulting the tracker. So when a user logs in, he will first go to any server according to Round and Robin algorithm, and from this server he will be redirected to the server storing his image, where he can get served, while eliminating the network communication overhead. </p> <p class="MsoNormal"><o:p> </o:p><br />This architecture can be implemented with any storage intensive application, or any application that used to rely on NFS, as NFS has proven to be unreliable in heavy production environments. </p> <p class="MsoNormal">I like this tool very much, and I can’t wait to test it on our application.. so I will keep you posted with any <span style=""> </span>updates.</p>Samer El Sahnhttp://www.blogger.com/profile/07314985878394159062noreply@blogger.com0tag:blogger.com,1999:blog-2858328690300381570.post-86405890975924528092007-05-12T17:19:00.000-07:002007-06-05T15:11:18.263-07:00Web AntivirusWeb Services are increasingly becoming an essential part of your everyday life. How much time you spend surfing the internet pages?<br /><div style="text-align: justify;">To be more specific how much you feel now that Google is too much involved in your daily routine? Can you imagine your life without Google? your search, your Calendar, your email, your blog, ...etc<br /></div><br /><div style="text-align: justify;">Well, it seems that you will look for Google to be your web antivirus. Before you access a page, type the url in google search and pray that you won't get "<i>this site may harm your computer</i>".<br /></div>you have just to obey, otherwise your PC will be affected.<br /><br /><div style="text-align: justify;">the story begins with researchers from the firm surveyed billions of sites, subjecting 4.5 million pages to "in-depth analysis". Actually they found 450,000 pages guilty.<br /></div><br />It is sufficient only one visit from you to make the attacker able to detect and exploit a browser<br /><div style="text-align: justify;">vulnerability. Therefore, the goal of the attacker becomes identifying web applications with vulnerabilities that enable him to insert small pieces of HTML in web pages.<br /></div><div style="text-align: justify;">An example for this is iframes, which can successfully install a malware binary "<span style="font-style: italic;">drive-by-download</span>".<br /></div>Are the web masters, or the site creators are responsible for this?<br />The answer is, it is not always the case<span style="font-weight: bold;">.<br /><br />User Contribution</span><br /><div style="text-align: justify;">Many web sites feature web applications that allow visitors to contribute their own content. This is often in the form of blogs, profiles, comments, or reviews. they usually support only a limited subset of the hypertext markup language, but in some cases poor sanitization or checking allows users to post or insert arbitrary HTML into web pages.<br /></div><span style="font-size:85%;"></span><br /><span style="font-weight: bold;">Advertising</span><br />Although web masters have no direct control over the ads themselves, they trust advertisers to show non-malicious content. Sometimes, advertisers rent out part of their advertising space; in this case the web master needs to trust the ads provided from a company that might be trusted by the first advertiser. And so on, you may find nested relations which considered as pitfall in the trust relation by making it a transitive one.<br /><br /><span style="font-weight: bold;">Third-Party Widgets<br /></span>A third-party widget is an embedded link to an external JavaScript or iframe that a web master uses to provide additional functionality to users. Example for this, Google Analytics :)<br /><br /><span style="font-weight: bold;">Webserver Security</span><br /><div style="text-align: justify;">The contents of a web site are only as secure as the set of applications used to deliver the content, including the actual HTTP server, scripting applications (e.g. PHP, ASP etc.) and database backends. If an attacker gains control of a server, he can modify its content to his benefit. For example, he can simply insert the exploit code into the web server’s templating system. As a result, all web pages on that server may start exhibiting malicious behavior. Although the team has observed a variety of web server compromises, the most common infection vector is via vulnerable scripting applications. They observed vulnerabilities in phpBB2 or InvisionBoard that enabled an adversary to gain direct access to the underlying operating system. That access can often be escalated to super-user privileges which in turn can be used to compromise any web server running on the compromised host. This type of exploitation is particularly damaging to large virtual hosting farms, turning them into malware distribution centers.<br /><br /><span style="font-weight: bold;">Exploitation Mechanisms<br /></span>A popular exploit they encountered takes advantage of a vulnerability in Microsoft’s Data Access Components that allows arbitrary code execution on a user’s computer.<br />Typical steps taken to leverage vulnerability into remote code execution:<br /><ul><li>The exploit is delivered to a user’s browser via an iframe on a compromised web page.</li><li>The iframe contains Javascript to instantiate an ActiveX object that is not normally safe for scripting.</li><li>The Javascript makes an XMLHTTP request to retrieve an executable.</li><li>Adodb.stream is used to write the executable to disk.</li><li>A Shell.Application is used to launch the newly written executable.</li></ul>Another popular exploit is due to a vulnerability in Microsoft’s<span style="font-weight: bold;"> WebViewFolderIcon</span>. The exploit Javascript uses a technique called <span style="font-style: italic;">"heap spraying</span>" which creates a large number of Javascript string objects on the heap. Each Javascript string contains x86 machine code (shellcode) necessary to download and execute a binary on the exploited system. By spraying the heap, an adversary attempts to create a copy of the shellcode at a known location in memory and then redirects program execution to it.<br /><br /><span style="font-weight: bold;">Detecting Dangerous Pages<br /></span>Simply, by monitoring the CPU and the processes executed on accessing the page. When some unknown processes are added to the list, this will be a strong sign that a drive-by download has happened.<br /><br />Google will be more and more involved into our life, it will report to you malicious sites for free....<br />anyway, it is not a big deal, you can do it yourself for some levels. but there a little bit sophisticated cases when you need multilevel reverse engineering...<br /><br />Reference: <a href="http://www.usenix.org/events/hotbots07/tech/full_papers/provos/provos.pdf">Google Research Paper</a><br /><br /><span style="font-size:85%;"><span style="font-weight: bold;">Update:</span><br /><a href="http://googleonlinesecurity.blogspot.com/">Google online security blog</a>, the latest news and insights from Google on security and safety on the internet.</span><br />Microsoft <a href="http://www.informationweek.com/windows/showArticle.jhtml?articleID=199901414&cid=RSSfeed_TechWeb">takes actions</a> to defend vulnerabilities claim.<br /><span style="font-weight: bold;"></span></div><span style="font-weight: bold;"></span>Ahmed Abd-ElHaffiez Husseinhttp://www.blogger.com/profile/09563341584184001660noreply@blogger.com2tag:blogger.com,1999:blog-2858328690300381570.post-47734662511310678412007-05-09T15:02:00.000-07:002007-05-09T15:04:18.784-07:00Upgrade your Experience with Google Analytics<p>Few days ago <a href="http://www.google.com/analytics/index.html">Google Analytics</a> has released a new version. The new user UI enables easier use of the reports and metrics within the data sets,</p> <p style="text-align: center;"><a href="http://www.flickr.com/photos/rustybrick/488630843/" title="Photo Sharing"><img src="http://farm1.static.flickr.com/211/488630843_ef1caf7388.jpg" alt="New Google Analytics Visitor Overview" height="449" width="500" /></a></p><span style="font-weight: bold;">NEW:</span><br /><ul><li>Email reports and improved clarity of graphs allow users to explore and discover new insights</li><li>Customizable dashboards ensure the right data gets to the right people at the right time</li><li>Plain language descriptions of the data allow users to take action to improve their web site</li></ul>This is awesome :)Ahmed Abd-ElHaffiez Husseinhttp://www.blogger.com/profile/09563341584184001660noreply@blogger.com0tag:blogger.com,1999:blog-2858328690300381570.post-91451230449280571332007-05-06T14:29:00.000-07:002007-05-21T10:26:24.105-07:00Where do you want to go today?<p class="MsoNormal">I have been conducting systems administration interviews for a while now, and I used to ask that one question in every interview, which is better “Linux” or “Windows”. I used to settle for a simple answer like “Depending on the environment”, this answer could get the guy into our payroll on the spot. This was in the old days when I was still young and foolish. In these old days, <span style=""> </span>I used to forgive my Windows when it hangs like forever, trying to do something I don’t know about, or when my server bails out of me for no good reason or with no trace, but you know people do grow up.</p> <p class="MsoNormal"><o:p></o:p>For a long period now I have been playing with operating systems, including Linux and Windows. After being a loyal follower to the Microsoft technologies, I had a paradigm shift. I saw the beauty of Linux, and I touched base with the meaning of operating system. And day after day I started to understand how Linux outperforms Windows, lets take for example, why does sometimes, Windows stop responding to your requests, and start playing busy. Your Hard disk lids start blinking, and no matter how much you click anywhere your computer never give you attention. In this article we will try to explain why this happens on Windows and rarely on Linux. </p> <p class="MsoNormal">Lets imagine your process getting into the OS and praying that it reaches the CPU before it starves. according to this <a href="http://widefox.pbwiki.com/Kernel%20Comparison%20Linux%20vs%20Windows">article</a>, In Windows, the Kernel scheduler has two queues, a foreground queue with Round and Robin algorithm and a background Queue with First in First out algorithm, and the scheduler uses many priority algorithms along with other algorithms to decide to get your poor process into which queue. The problem here that Windows scheduler works with a multilevel queue technique, meaning once you are in the queue you are stuck there until your time come to get into the CPU or starve to death.. its simple.. but a retarded one too. So, what happens when many background processes get into the background queue? These processes are not time sliced as the ones in the foreground queue, so once they get in, they will never get out until they finish.. and to make things even better the scheduler chooses between the two queues with a probability of 80% for the background queue to 20% for the foreground queues, so if odds are against you, which seems to be always this way with me, your process has to wait a long time until it get served, and so all what you get is the freezing screen and the busy Hard disk signal.</p> <p class="MsoNormal">So what does Linux do, Linux scheduler is a bit smarter, it uses a technique called multilevel queue with feedback. Hmmmm.. Feedback gives the impression that the process is able to discuss its state with the scheduler, and not like windows accept its fate to be doomed in the never lands. Yes, Linux has more than two queues with different algorithms and priority, and processes can move from one queue to another according to its state, so if a process was stuck for a long time in a queue and didn’t get served, its priority increase and it get moved to another VIP queue where processes get served at once.</p> <p class="MsoNormal">Some say all this complexity in the Linux scheduler will create an overhead and slow things down when you have a large number of processes. But Linux uses O(1) scheduling algorithms, so as Windows to give it credit, which means its not subject to the number of processes, and its smart, and it really respect your requests and doesn’t give you the sense that the computer is doing a much more important thing than your pathetic request.</p> <p class="MsoNormal">So where do you want to go today? I know where I am going.</p> <p class="MsoNormal"><o:p> </o:p></p>Samer El Sahnhttp://www.blogger.com/profile/07314985878394159062noreply@blogger.com0