skip to main | skip to sidebar

Friday, October 16, 2009

Hosting Multiple Domains In Tomcat

Tomcat allows us to host multiple domains in one instance, using multiple 'Host' tags. In this article I will explain how to do it on Tomcat. This is very simple configuration using 'Host' tags in your server.xml. A novice can also understand this configuration very easily.
Before going into the details of the configuration first lets have a look at the 'Host' tag, 'Context' tag and 'Alias' tags first.
   <Host name="domain1" appBase="[application base]" autoDeploy="[true/false]" 
        unpackWARs="[true/false]">
    <Alias>...</Alias>
    <Context path="" docBase="" reloadable="[true/false]"/>
   </Host>
  
First lets have a look at 'Alias' tag. This tag is used to provide aliases for your actual domain. For example you have a domain called 'domain1.com', and you want to run the same application for 'www.domain1.com' also, then you can use this 'Alias' tag to provide an alias name for the actual domain.
   <Host name="domain1.com" ...>
    <Alias>www.domain1.com</Alias>
    <Alias>domain1.net</Alias>
    <Alias>www.domain1.net</Alias>
    ...
   </Host>
  
As you can see in the above example, if you want to have multiple aliases you can add multiple 'Alias' tags for each domain alias name.
Now lets move on to the 'Context' tag. The 'Context' element represents a web application running inside a host. To explain this in an easy way; each directory under 'webapps' directory of your tomcat is one context. Manager and Admin consoles of your tomcat installation are two different contexts running under your 'localhost' domain.
   <Context path="" docBase="" reloadable="[true/false]"/>
  
In the above code snippet I've provided minimum configuration needed for a context. Lets go through the attributes of 'Context' tag.
'path' attribute - here we need to give the relative URL [to the host URL in which this Context is being configured] of the context. Say you want to run the application from "domain.com/beta" then the 'path' attribute needs to be "/beta".
'docBase' - the Document Base directory. Here we need to give the root directory for this context. This can be an absolute path to the directory/WAR file OR relative to the 'appBase' given in the 'Host' tag. If the context root directory is inside the 'appBase' directory of the 'Host' tag then we can give it as
   docBase="."
  
'reloadable', it defaults to 'false'. If you give 'true' to this value, tomcat looks for changes in the 'WEB-INF/classes' or 'WEB-INF/lib' directory and reloads the context automatically. This will useful in development environment, so that a new deployment doesn't result restarting tomcat. But on production server its better to leave the default value as setting it to true results an overhead on the server.
Now the 'Host' tag - it represents a host [also called as Virtual Host] running, associated with a domain name in the server. We can have multiple 'Host' tags to host multiple domains in one tomcat. Lets see the attributes.
   <Host name="domain1" appBase="[application base]" autoDeploy="[true/false]" 
        unpackWARs="[true/false]">
   ...
   <Host/>
  
'name' - Domain Name attribute. Here we need to give the domain name which you are trying to host/deploy.
'appBase' - Application Base Directory attribute. Here we need to give the root directory for this application which contains web applications to be deployed on this host. It can be either an absolute path to the directory OR relative to the 'CATALINA_BASE' directory.
'autoDeploy' - flag to denote newly placed web applications should be deployed automatically. If this attribute is set to true and you place a WAR file OR a Web application directory in 'appBase' then tomcat automatically deploys the application.
'unpackWARs' - if set to true Tomcat will automatically unpack the WAR files placed in to corresponding directory structure.
Now lets look at the configuration to host multiple domains.
   <Engine defaultHost="domain1.com" name="Catalina">
    <Host name="domain1.com" appBase="/home/user1/domain1">
     <Alias>www.domain1.com</Alias>
     <Context path="" docBase="."/>
    </Host>
    <Host name="domain2.com" appBase="/home/user1/domain2">
     <Alias>www.domain2.com</Alias>
     <Context path="" docBase="."/>
    </Host>
    <Host name="domain3.com" appBase="/home/user1/domain3">
     <Alias>www.domain2.com</Alias>
     <Context path="" docBase="."/>
    </Host>
   </Engine>
  
In the above configuration we tried to host three domains in Tomcat. We added three 'Host' tags one for each domain we wanted to host. Each domain points to a different ['appBase'] directory [I used absolute paths for 'appBase' attribute, it can be relative to CATALINA_BASE].
That's it for now!
Reference URLs
Read more »»

Saturday, October 10, 2009

String manipulation in Java

One topic most of the developers in early days of their career overlook while programming is STRING MANIPULATION. This article will throw some light on this topic, so that one can make habit of some efficient coding. I am going to give some insight into Java string manipulation and some better ways to do string manipulation.
In Java String objects are immutable, what it means is once you create a String object in Java, it can not be changed/modified. For example look at the following code.
   String a = "A String Object";
   a = "Second String Object";
  
In the above code, we created a String object 'a' at line#1 with the value "A String Object", and in line#2 we tried to change the value of the object 'a' to "Second String Object". As I mentioned little earlier, when you create a String object in Java, it can not be changed. In line#2 when you try to change the value of object 'a', JVM [Java Virtual Machine] will create a new String object with the new value and assign its reference to object 'a', and the old reference will be marked for garbage collection. Let's look at another piece of code.
   String a = "A String Object, ";
   a = a + "created in Java";
  
It looks almost similar to the first piece of code. Difference is after creating a String object at line#1, at line#2 - we tried to append another string "created in Java" to the existing one. Obviously result we expected is "A String Object, created in Java". Internally what JVM does is it creates a new Java object with the new appended string and assigns its reference to object 'a', old references will be marked for garbage collection.
This cost of this string manipulation [above pieces of code] might look negligible to any one, but think about an application with pieces of code like the one above spread all over its source. Think how many String objects gets created and marked for garbage collection at one run. This all results to many CPU cycles allocated for creation of String objects and garbage collecting unreferenced String Objects.
Now let's look at one way of doing String manipulation in a better way. Java provides two classes which allow you to modify String values.
These two objects are almost same with only one difference. StringBuilder class is unsynchronized, where are StringBuffer is synchronized. In short StringBuffer is thread safe, where as StringBuilder is not. We can use these classes to do String manipulation efficiently in our code. When to use StringBuilder and when to use StringBuffer? Answer to this question is when your code is accessed by single thread at any time then it is better to use StringBuilder, which gives better performance in this scenario. And when your code is accessed by multiple threads then you need to use StringBuffer because its thread safe.
Now lets look at an example using one of these classes. Think of a situation where you have String objects representing parts of address of one user/company or something like that. Think that you've four String objects 'streetAddress', 'city', 'state', and 'country' with values initialized properly, and you want to generate one String with all these values. For example if the above mentioned objects are initialized as given below,
   streetAddress = "Plot#10, Road#7";
   city = "Hyderabad";
   state = "Andhrapradesh";
   country = "India";
  
And you want to have a composite string like "Plot#10, Road#7, Hyderabad, Andhrapradesh, India". One inefficient way of doing is using the overloaded '+' operator like
   streetAddress + "," + city + "," + state + "," + country
  
Now the better way using StringBuilder class is
   StringBuilder sb = new StringBuilder();
   sb.append(streetAddress).appent(',').append(city).append(',')
     .append(state).append(',').append(country);
  
Most common place where developers can improve string manipulation related code is JSP pages. If you take the above example, to print the address, some developers code it like
   <%=streetAddress + "," + city + "," + state + "," + country %>
  
In a JSP page one object [instance of JSPWriter, 'out' object available on a JSP] will already be created to generate the output. If you write code which is similar to the one above, JVM creates unnecessary String objects for each of the '+' operator you use. After reading this article till this point you can think of using StringBuilder/StringBuffer, but that might not be the correct way to do it. Why?, as I mentioned above there will be one object 'out' created already, creating another StringBuilder/StringBuffer object doesn't make sense. Then obvious solution is to use the 'out'. You can write something like the one below to generate the address string.
   <%=streedAddress%>, <%=city%>, <%=state%>, <%=country%>
  
If you think the above code makes the JSP look little complex, then you can write a static method to do the job for you. This method can take the 'out' object [JSPWriter instance] and the values to be appended. In that method you can call the 'append()' method on JSPWriter object 'out' to append the values.
That is all I have for now, about String manipulation. Hope it helps some guys to do some efficient coding.
HAPPY CODING!
Technorati Profile
Read more »»

Friday, October 9, 2009

Simple Accordion using Java Script and CSS

Well you can find many online, but it's difficult to find one with out any dependent API. Most of the available accordions use other APIs for animation and other stuff. For those who just want accordion with out any other stuff, this one is the perfect one. It's very simple and you don't have to be a geek to understand it. Basic knowledge of Java script and CSS will do to understand how this works. In this article I'll take you through the steps of developing an accordion. Couple of minutes you are ready to write your own. Well then let's start developing one.

Layout of the HTML block looks something like the one below
Layout
Lets look at the CSS first which is very simple.
/** container styles **/
   .ra-p, .ra-cp {
    padding: 0 0 0.1em;
   }
   /**** heading styles ****/
   .ra-p h2, .ra-cp h2 {
     margin: 0px;
     padding: 0.2em;
     cursor: pointer;
     color: #fff;
     background-color: #3d80b0;
   }
   /**** collapsed heading styles ****/
   .ra-cp h2  {
     Background-color: #3d80b0;
   }
   /**** content styles *****/
   .ra-p .text, .ra-cp .text { overflow: hidden; }
   /**** hide collapsed content ****/
   .ra-cp .text { display: none; }
This all you need. Lets go through it.
First you've '.ra-p' and '.ra-cp' which are applied to the container ['ra-p' for expanded one, 'ra-cp' for collapsed one]. Then we've styles for the heading/title, 'ra-p h2', 'ra-cp h2'. As we are going to use 'h2' as heading tags we've styles for 'h2'. Finally we've styles for the content block, '.ra-p .text' and '.ra-cp .text'.
And now we'll go through the java script need for it.
Accordion = function(el, delay, steps) {
    if (!el) {
     alert('Element required to make it a Accordion.');
     return;
    }
    this.init(el, delay, steps);
   }
  
This code block is self explanatory. This is a constructor which initializes an Accordion. It takes three parameters.
  • el - The element [block which need to work as an accordion].
  • delay - Time delay in animating the accordion.
  • steps - Number of steps for the animation.
First it checks whether the element is available, if not then gives an alert message and returns. If the element exists then continues by calling the 'init()' method. Before looking into the 'init()' method, lets add some supportive methods needed by the code.
For convention I am going to use '_' as prefix to the method names which are internal to the code, so that you can easily identify which methods are internal and which are available for external code. We need
  • A method to check for applied CSS styles.
  • A method to get individual elements from the block which works as Accordion.
  • A method to calculate step height for animation.
First lets see the method to check for applied CSS styles.
_hasClass : function(c, className) {
    return c.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'));
   }
  
As this is an internal method it is prefixed with '_' as mentioned little earlier. It takes two parameters.
  • The html tag element/node for which we need to check for applied styles.
  • The CSS class name.
This method uses Regular Expression to check CSS styles applied for efficiency. The regular expression used is "new RegExp('(\\s|^)' + className + '(\\s|$)')". In this regular expression '\s' denotes any white-space character, '|' is for alternation [logical OR], '^' is to match for string starting, and the CSS class name we wanted to check for [method parameter 'className'], followed by any white-space character '\s', '|' for alternation [logical OR], and '$' to math for end of string.
I think this explanation gives you good idea how the regular expression works. Now if we see the one line in the method '_hasClass' it uses the DOM attribute 'className' to get the applied CSS classes to the element passed and uses regular expression to find matches. If it finds a match then it returns true, false otherwise.
The next method we have is the one to get elements from an html block [method to get matching child element from the given container element]. Let's name it as '_getElement'.
_getElement : function(parent, childTag, className) {
    var elements = this.el.getElementsByTagName(childTag);
    if (!className)
     return elements[0];
    for (var i=0; i < elements.length; i++) {
     if (this._hasClass(elements[i], className))
      return elements[i];
    }
   }
  
This method takes three parameters.
  • The parent/container element in which we are going to look for matching child elements.
  • The type of the child tag we need to look for.
  • CSS class name, which is applied to the child tag we are looking for.
If we do not pass any CSS class then, this method return the first element matching the given child tag type. We use 'getElementsByTagName ()' method which takes the tag type to be looked for and returns all the matching child tags as an array.
After we get the array of matching child tags, we loop through them and check each element, whether it has the given CSS class applied to it. When it finds a match it returns the element.
Now we need a method to calculate the step height for animation of accordion, let's name it as '_getStepHeight'
_getStepHeight : function () {
    // make sure the content is visible before getting its height
    this.contentEl.style.display = "block";
    // get the height of the content
    var contentHeight = this.contentEl.offsetHeight;
    return (contentHeight / this.steps);
   },
  
This method is very simple; first it gets the height of the block [accordion block] and divides it by the number of steps. To get the height of the block, first we set the 'display' attribute of it to 'block' so that we get the proper height even if the block is in closed status.
Now lets move on to the 'init()'method.
init : function(el, delay, steps) {
    /** Accordion element**/
    this.el = el;
    /** Accordion heading tag - mouse events will be attached to this tag **/
    this.headingTag = "h2";
    /** delay for each step of animation **/ 
    this.delay = delay;
    /** no.of animation steps **/
    this.steps = steps;
    /** CSS classes of container and heading panels **/
    this.panelClass = "ra-p";
    this.cPanelClass = "ra-cp";
    this.textClass = "text";

    /** attach mouse click events **/
    if (this._hasClass(el, this.panelClass)) {
     this.contentEl = this._getElement(el, "div", this.textClass);
     this.headerEl = this._getElement(el, "h2");
     /** calculate animation step size **/
     this.stepHeight = this._getStepHeight();
     if (this.contentEl && this.headerEl) {
      var panel = this;
      this.headerEl.onclick = function() { 
       panel.animateToggle(panel); 
      };
     }
    }
   }
  
Most part of this method is just initialization of variables. First half of the method we'll initialize variables used for accordion animation. Important part is the one where we add mouse click event to the block heading. Before adding mouse event to the heading we verify that the container had the necessary CSS ['ra-p' in this case] applied to it. You can see these values initialized in the first half of the method.
Then we'll get the content block element reference and keep its reference ['contentEl' variable], and we'll get the heading element reference ['headerEl' variable]. After this we'll calculate the step height [height in pixels for each step of animation] for animation.
Before proceeding to add mouse click event, we'll verify both content element and header elements are available, finally we'll add mouse click event handler and attaché 'animateToggle ()' method. That's it we are almost done with this. Only thing we are left with is the 'animateToggle ()' method, lets see what it has.
animateToggle : function(panel) {
    // check if you are in the middle of an operation
    if (this.key) {
     clearInterval(this.key);
     this.key = null;
    }
    // make sure the content is visible before getting its height
    this.contentEl.style.display = "block";
    var expanding = panel._hasClass(this.el, this.cPanelClass);
    // if panel is collapsed and expanding, we must start with 0 height
    if (expanding)
     panel.contentEl.style.height = "0px";
    this.iteration = 1;
    this.key = setInterval(function(){panel._animate(panel, expanding)}, panel.delay);
   }
  
Surprisingly nothing complex here!; first we'll check whether we are in the middle of an existing opration [expanding/collapsing], if we are, then we'll stop it by calling 'clearInterval()' method and continue with the current one.
Then we'll make sure that the content block is visible by setting its 'display' property to 'block', and then see whether we're expanding the block or collapsing it by checking CSS style applied to it. If it has 'ra-p' then block is expanded and we need to collapse it, expand otherwise. If we're expanding set the content block's height to '0px' and start increasing its height. To increase the height step by step we'll call an internal function '_animate()' repeatedly after specific delay using 'setInterval()' method. 'setInterval()' method is available in java script which can be used to call a method repeatedly after some delay until we call it to stop, using 'clearInterval()'.
Lets see what '_animate()' method has in it.
_animate : function (panel, expanding) {
    if (panel.iteration < panel.steps) {
     panel.contentEl.style.height = Math.round(
       ((expanding) ? panel.iteration : 
        panel.steps - panel.iteration) * panel.stepHeight) +"px";
     panel.iteration++;
    } else {
     // set class for the panel
     panel.el.className = (!expanding) ? panel.cPanelClass : panel.panelClass;
     // clear inline styles
     panel.contentEl.style.display = panel.contentEl.style.height = "";
     // stop animation
     clearInterval(this.key);
     this.key = null;
    }
   }
  
At the beginning we specified the number of steps for the animation and this is what we use to stop animation. Fist we check whether the iteration is less that number of steps. If yes we'll proceed with increasing/decreasing the height of the content block. Else we'll reset the CSS styles for the content block and stop animation.
You can download the complete code using the link bellow. Click here.
This post might look lengthy, but when you see the code, it's very small and light in size. Hope it's useful for some folks out there looking for similar code.
By the way it's my first posting, I'd love to get some feedback. Do drop a note!
Read more »»

About Rakesh.A

Rakesh Reddy
As the URL and other parts of this blog says, I am Rakesh.A, a techie form Hyderabad, India. I am working for coMakeIT, Hyderabad as a Sr. Software Engineer, that's about me in short.
How I ended up in this profession? - Well when I was doing my schooling I never thought I'll be into this profession, infact I wasn't that interested in Information Technology/Software Development, so never concentrated on it even after my parents stressed to get into it. After couple of years, I saw myself doing the same. And now I can't even think of myself being in a different profession. Anything I can do with whole heart, that's only PROGRAMMING/DEVELOPMENT.
As every student who got into this profession, I felt my FIRST LOVE with 'C language', and I love coding in C. Then I started learning Object Oriented Programming and got attracted to 'C++ language', but it was 'JAVA' in which I saw my soul mate. That's it I got married to it and settled. I've been working on various Java Technologies since I started my career, and I love to program in Java. When ever I develop an application, I feel like an Artist marvel about his Art work, funny right :), but that's how I feel.
After being into this profession for couple of years, I learnt great deal of things from great people I worked with, and then one day I thought why can't I share this knowledge to others, and be helpful to those who need it!.
I actually have big ideas for this concept, but couldn't find time to fulfill it, so as an initiation towards what I dreamt, I started this blog. I'll be posting about things I learnt about efficient programming to other related things like Web/App servers, build scripts, etc. In short all the things I know, and I learnt. Hope this blog helps few people who are looking for it.
Now so much about technical things, apart from Programming/Development, I love reading books, and love playing Badminton, and Cricket. I spend most of my time at home - reading, coding, watching TV and occasionally get into kitchen :), I don't like to go out and have fun, but I love to go to movies with friends. My favorites - God Father, Lord of the Rings trilogies, Good Fellas, Galdiator... list goes on!
Read more »»