Your Ad Here

Saturday, July 12, 2008

How to set JNDI in Hibernate?

How to set JNDI in Hibernate?

Configuration for Tomcat and Jboss is almost same.

I did check in both it is working.

Set the following in Hibernate.hbm and then set the datasource in jndi config file.


<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<!-- a SessionFactory instance listed as /jndi/name -->
<session-factory
name="java:hibernate/SessionFactory">

<!-- properties -->
<property name="connection.datasource">java:/comp/env/jdbc/MyDB</property>
<property name="dialect">org.hibernate.dialect.SCJASQLDialect</property>
<property name="show_sql">true</property>
<property name="transaction.factory_class">
org.hibernate.transaction.JTATransactionFactory
</property>
<property name="jta.UserTransaction">java:comp/UserTransaction</property>

<!-- mapping files -->

<!-- cache settings -->

</session-factory>

</hibernate-configuration>

server.xml configuration

Configure the JNDI DataSource in Tomcat by adding a declaration for your resource to $CATALINA_HOME/conf/server.xml.

Add this in between the </Context> tag of the examples context and the </Host> tag closing the localhost definition.

<Context path="/DBTest" docBase="DBTest"
        debug="5" reloadable="true" crossContext="true">
 
  <Logger className="org.apache.catalina.logger.FileLogger"
             prefix="localhost_DBTest_log." suffix=".txt"
             timestamp="true"/>
 
  <Resource name="jdbc/MyDB"
               auth="Container"
               type="javax.sql.DataSource"/>
 
  <ResourceParams name="jdbc/MyDB">
    <parameter>
      <name>factory</name>
      <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
    </parameter>
 
    <!-- Maximum number of dB connections in pool. Make sure you
         configure your mysqld max_connections large enough to handle
         all of your db connections. Set to 0 for no limit.
         -->
    <parameter>
      <name>maxActive</name>
      <value>100</value>
    </parameter>
 
    <!-- Maximum number of idle dB connections to retain in pool.
         Set to 0 for no limit.
         -->
    <parameter>
      <name>maxIdle</name>
      <value>30</value>
    </parameter>
 
    <!-- Maximum time to wait for a dB connection to become available
         in ms, in this example 10 seconds. An Exception is thrown if
         this timeout is exceeded.  Set to -1 to wait indefinitely.
         -->
    <parameter>
      <name>maxWait</name>
      <value>10000</value>
    </parameter>
 
    <!-- MySQL dB username and password for dB connections  -->
    <parameter>
     <name>username</name>
     <value>javauser</value>
    </parameter>
    <parameter>
     <name>password</name>
     <value>javadude</value>
    </parameter>
 
    <!-- Class name for mm.mysql JDBC driver -->
    <parameter>
       <name>driverClassName</name>
       <value>org.gjt.mm.mysql.Driver</value>
    </parameter>
 
    <!-- The JDBC connection url for connecting to your MySQL dB.
         The autoReconnect=true argument to the url makes sure that the
         mm.mysql JDBC Driver will automatically reconnect if mysqld closed the
         connection.  mysqld by default closes idle connections after 8 hours.
         -->
    <parameter>
      <name>url</name>
      <value>jdbc:mysql://localhost:3306/javatest?autoReconnect=true</value>
    </parameter>
  </ResourceParams>
</Context>

Friday, July 11, 2008

Warn if not Subject in outlook mail

This is really useful………

Forgot to mention subject, while writing an official mail and feel bad later???????

Yes…. It’s a concern for all…. A mail without a subject brings a bad impression on us.

To avoid this, Just follow the simple steps mentioned below and see the result.

Here below are the steps: -

1. Open your outlook

2. Press Alt+F11. This opens the Visual Basic editor

3. On the Left Pane, one can see "Microsoft Outlook Objects" or "Project1", expand this. Now one can see the "ThisOutLookSession".

4. Double click on "ThisOutLookSession". It will open up a code pane.

5. Copy and Paste the following code in the right pane. (Code Pane)

‘=============================================================================================

Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)

Dim strSubject As String

strSubject = Item.Subject

If Len(Trim(strSubject)) = 0 Then

Prompt$ = "Subject is Empty. Are you sure you want to send the Mail?"

If MsgBox(Prompt$, vbYesNo + vbQuestion + vbMsgBoxSetForeground, "Check for Subject") = vbNo Then

Cancel = True

End If

End If

End Sub

‘=============================================================================================

6. Save this and now close the VB Code editor.

From now on, this macro will make sure you do not make the mistake of sending a mail without a subject.

Wednesday, July 2, 2008

Hibernate Dielect example

Hibernate Dielect example

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">

com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">

jdbc:mysql://localhost/hibernatetutorial</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password"></property>
<property name="hibernate.connection.pool_size">10</property>
<property name="show_sql">true</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- Mapping files -->
<mapping resource="contact.hbm.xml"/>
</session-factory>
</hibernate-configuration>

In the above configuration file we specified to use the "hibernatetutorial" which is running on localhost and the user of the database is root with no password. The dialect property is org.hibernate.dialect.MySQLDialect which tells the Hibernate that we are using MySQL Database. Hibernate supports many database. With the use of the Hibernate (Object/Relational Mapping and Transparent Object Persistence for Java and SQL Databases), we can use the following databases dialect type property:

  • DB2- org.hibernate.dialect.DB2Dialect
  • HypersonicSQL - org.hibernate.dialect.HSQLDialect
  • Informix - org.hibernate.dialect.InformixDialect
  • Ingres - org.hibernate.dialect.IngresDialect
  • Interbase - org.hibernate.dialect.InterbaseDialect
  • Pointbase - org.hibernate.dialect.PointbaseDialect
  • PostgreSQL - org.hibernate.dialect.PostgreSQLDialect
  • Mckoi SQL - org.hibernate.dialect.MckoiDialect
  • Microsoft SQL Server - org.hibernate.dialect.SQLServerDialect
  • MySQL - org.hibernate.dialect.MySQLDialect
  • Oracle (any version) - org.hibernate.dialect.OracleDialect
  • Oracle 9 - org.hibernate.dialect.Oracle9Dialect
  • Progress - org.hibernate.dialect.ProgressDialect
  • FrontBase - org.hibernate.dialect.FrontbaseDialect
  • SAP DB - org.hibernate.dialect.SAPDBDialect
  • Sybase - org.hibernate.dialect.SybaseDialect
  • Sybase Anywhere - org.hibernate.dialect.SybaseAnywhereDialect

The <mapping resource="contact.hbm.xml"/> property is the mapping for our contact table.

Writing First Persistence Class
Hibernate uses the Plain Old Java Objects (POJOs) classes to map to the database table. We can configure the variables to map to the database column. Here is the code for Contact.java:

package com.hibernate;

public class Contact {
private String firstName;
private String lastName;
private String email;
private long id;

/**
* @return Email
*/
public String getEmail() {
return email;
}

/**
* @return First Name
*/
public String getFirstName() {
return firstName;
}

/**
* @return Last name
*/
public String getLastName() {
return lastName;
}

/**
* @param string Sets the Email
*/
public void setEmail(String string) {
email = string;
}

/**
* @param string Sets the First Name
*/
public void setFirstName(String string) {
firstName = string;
}

/**
* @param string sets the Last Name
*/
public void setLastName(String string) {
lastName = string;
}

/**
* @return ID Returns ID
*/
public long getId() {
return id;
}

/**
* @param l Sets the ID
*/
public void setId(long l) {
id = l;
}

}

Mapping the Contact Object to the Database Contact table
The file contact.hbm.xml is used to map Contact Object to the Contact table in the database. Here is the code for contact.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="example.hibernate.Contact" table="CONTACT">
<id name="id" type="long" column="ID" >
<generator class="assigned"/>
</id>

<property name="firstName">
<column name="FIRSTNAME" />
</property>
<property name="lastName">
<column name="LASTNAME"/>
</property>
<property name="email">
<column name="EMAIL"/>
</property>
</class>
</hibernate-mapping>

Setting Up MySQL Database
In the configuration file(hibernate.cfg.xml) we have specified to use hibernatetutorial database running on localhost. So, create the databse ("hibernatetutorial") on the MySQL server running on localhost.

Developing Code to Test Hibernate example
Now we are ready to write a program to insert the data into database. We should first understand about the Hibernate's Session. Hibernate Session is the main runtime interface between a Java application and Hibernate. First we are required to get the Hibernate Session.SessionFactory allows application to create the Hibernate Sesssion by reading the configuration from hibernate.cfg.xml file. Then the save method on session object is used to save the contact information to the database:

session.save(contact)

Here is the code of FirstExample.java

package com.hibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;


public class FirstExample {
public static void main(String[] args) {
Session session = null;

try{
// This step will read hibernate.cfg.xml

and prepare hibernate for use
SessionFactory sessionFactory = new

Configuration().configure().buildSessionFactory();
session =sessionFactory.openSession();
//Create new instance of Contact and set

values in it by reading them from form object
System.out.println("Inserting Record");
Contact contact = new Contact();
contact.setId(3);
contact.setFirstName("satish");
contact.setLastName("Kumar");
contact.setEmail("rachasatish@gmail.com");
session.save(contact);
System.out.println("Done");
}catch(Exception e){
System.out.println(e.getMessage());
}finally{
// Actual contact insertion will happen at this step
session.flush();
session.close();

}

}
}

Web stats- Urchin

This software is used to track the logs of IIS and apache and displays reports.

  • In-house Flexibility: Configure Urchin to fit your specific requirements and process/reprocess log files as frequently as you wish.
  • Great for intranets: Analyze firewall-protected content, such as corporate intranets, without any outside internet connection.
  • Pagetags or IP+User Agent: Choose which methodology works best for you. You can even have the pagetags make a call to your Google Analytics account and run both products together allowing you to audit the pre and post processed data.
  • Advanced Visitor Segmentation: Cross segment visitor behavior by language, geographic location, and other factors.
  • Geo-targeting: Find out where your visitors come from and which markets have the greatest profit potential.
  • Funnel Visualization: Eliminate conversion bottlenecks and reduce the numbers of prospects who drift away unconverted.
  • Complete Conversion Metrics: See ROI, revenue per click, average visitor value and more.
  • Keyword Analysis: Compare conversion metrics across search engines and keywords.
  • A/B Test Reporting: Test banner ads, emails, and keywords and fine-tune your creative content for better results.
  • Ecommerce Analytics: Trace transactions to campaigns and keywords, get loyalty and latency metrics, and see product merchandising reports.
  • Search engine robots, server errors and file type reports: Get the stuff that only log data can report on.
  • Visitor History Drilldown: dig into visitor behavior with the ability to view session/path, platform, geo-location, browser/platform, etc. data on an individual-visitor basis (note: this data is anonymous).
Feature Urchin 6 Google Analytics
Install and manage on your own servers Yes No
Can be used on firewall-protected corporate intranets Yes No
Reprocess historical data (from logfiles) Yes No
Can process/re-process your log files locally Yes No
Can collect information through tags No Yes
Reports on robot/spider activity Yes No
Reports on server errors/status codes Yes No
Tightly integrated with AdWords No Yes
Can report on paid search campaigns Yes Yes
Ecommerce/Conversion reporting Yes Yes
Geotargeting Yes Yes
Free No Yes
Visitor session/navigation path analyses Yes No
Raw data accessible for custom report-building Yes No
Exclusively supported by authorized consultants Yes No

http://www.urchin.com

Web Statistics -AWStats

AWStats is short for Advanced Web Statistics. AWStats is powerful log analyzer which creates advanced web, ftp, mail
and streaming server statistics reports based on the rich data contained in server logs. Data is graphically presented in
easy to read web pages.
Designed with flexibility in mind, AWStats can be run through a web browser CGI (common gateway interface) or directly
from the operating system command line. Through the use of intermediary data base files, AWStats is able to quickly
process large log files, as often desired. With support for both standard and custom log format definitions, AWStats can
analyze log files from Apache (NCSA combined/XLF/ELF or common/CLF log format), Microsoft's IIS (W3C log format),
WebStar and most web, proxy, wap and streaming media servers as well as ftp and mail server logs.

AWStats' reports include a wide range of information on your web site usage:
* Number of Visits, and number of Unique visitors.
* Visit duration and latest visits.
* Authenticated Users, and latest authenticated visits.
* Usage by Months, Days of week and Hours of the day (pages, hits, KB).
* Domains/countries (and regions, cities and ISP with Maxmind proprietary geo databases) of visitor's hosts (pages, hits, KB,
269 domains/countries detected).
* Hosts list, latest visits and unresolved IP addresses list.
* Most viewed, Entry and Exit pages.
* Most commonly requested File types.
* Web Compression statistics (for Apache servers using mod_gzip or mod_deflate modules).
* Visitor's Browsers (pages, hits, KB for each browser, each version, 123 browsers detected: Web, Wap, Streaming Media
browsers…, around 482 with the "phone browsers" database).
* Visitor's Operating Systems (pages, hits, KB for each OS, 45 OS detected).
* Robots visits, including search engine crawlers (381 robots detected).
* Search engines, Keywords and Phrases used to find your site (The 122 most famous search engines are detected like
Yahoo, Google, Altavista, etc…)
* HTTP Errors (Page Not Found with latest referrer, …).
* User defined reports based on url, url parameters, referrer (referer) fields extend AWStats' capabilities to provide even
greater technical and marketing information.
* Number of times your site is added to Bookmarks / Favorites.
* Screen size (to capture this, some HTML tags must be added to a site's home page).
* Ratio of integrated Browser Support for: Java, Flash, Real G2 player, Quicktime reader, PDF reader, WMA reader (as
above, requires insertion of HTML tags in site's home page).
* Cluster distribution for load balanced servers.
In addition, AWStats provides the following:
* Wide range of log formats. AWStats can analyze: Apache NCSA combined (XLF/ELF) or common (CLF) log files,
Microsoft IIS log files (W3C), WebStar native log files and other web, proxy, wap, streaming media, ftp and mail server log
files. See AWStats F.A.Q. for examples.
* Reports can be run from the operating system command line and from a web browser as a CGI (common gateway
interface). In CGI mode, dynamic filter capabilities are available for many charts.
* Statistics update can be run from a web browser as well as scheduled for automatic processing.
* Unlimited log file size
What is AWStats / Features Overview 2/87 13/04/2008
* Load balancing system split log files.
* Support 'nearly sorted' log files, even for entry and exit pages.
* Reverse DNS lookup before or during analysis; supports DNS cache files.
* Country detection from IP location (geoip) or domain name.
* Plugins for US/Canadian Regions, Cities and major countries regions, ISP and/or Organizations reports (require non free
third product geoipregion, geoipcity, geoipisp and/or geoiporg database).
* WhoIS lookup links.
* Vast array of configurable options/filters and plugins supported.
* Modular design supports inclusion of addition features via plugins.
* Multi−named web sites supported (virtual servers, great for web−hosting providers).
* Cross Site Scripting Attacks protection.
* Reports available in many international languages. See AWStats F.A.Q. for full list. Users can provide files for additional
languages not yet available.
* No need for esoteric perl libraries. AWStats works with all basic perl interpreters.
* Dynamic reports through a CGI interface.
* Static reports in one or framed HTML or XHTML pages; experimental PDF export through 3rd party "htmldoc" software.
* Customize look and color scheme to match your site design; with or without CSS (cascading style sheets).
* Help and HTML tooltips available in reports.
* Easy to use − all configuration directives are confined to one file for each site.
* Analysis database can be stored in XML format for easier use by external applications, like XSLT processing (one xslt
transform example provided).
* A Webmin module is supplied.
* Absolutely free (even for web hosting providers); source code is included (GNU General Public License).
* Works on all platforms with Perl support.
* AWStats has a XML Portable Application Description.
Requirements:
AWStats usage has the following requirements:
* You must have access to the server logs for the reporting you want to perform (web/ftp/mail).
* You must be able to run perl scripts (.pl files) from command line and/or as a CGI. If not, you can solve this by
downloading latest Perl version at ActivePerl (Win32) or Perl.com (Unix/Linux/Other).

reference : http://awstats.sourceforge.net/

Sunday, June 29, 2008

Problem in removing elements from a collection using For-Loop

For-loops allows to traverse a collection but when I tried to remove elements from a collection in For-loop it so happened that after deleting one element at particular location in collection, the positions of rest of the element in collection changed and when I again tried to delete another element in the same loop the element hasn't got deleted.

Firstly I thought that this problem may be solved by using size() method in for statement as

<!--[if gte vml 1]&gt; &lt;![endif]--><!--[if !vml]--><!--[endif]--><!--[if !supportLineBreakNewLine]-->
<!--[endif]-->

because may be change in size of collection dynamically causing the problem. But I this solution didn't work.

I concluded from this that whenever we delete multiple elements in same for-loop some of the elements are missed or skipped due to shuffling of positions during the loop.

Also, there is a need of generic method to traverse and modify any form of collection. An iterator can be used for this purpose.

We need to see the element before we can decide that it is the one that should be removed from a collection. But in for-loop it is not necessary to lookup and then change. That is use of for-loop can make an attempt to change or remove an element without looking in it. So a tightly coupled mechanism for lookup and then change is needed. An iterator of collection Framework can be useful in solving this problem.

To find how for-loop caused problem and how iterator can solve this I have discussed about following in this BLOG:

1.Problem with For-Loop.
2.How Iterator are different from For-loop
3.Concept of Removing Elements using Iterator
4.For-Each Construct: The Enhanced For-Loop
5.Problem and Restrictions with the enhanced for loop
6.Example: JDOM multiple element deletion from ElementList problem
7.An Example of remove element using For-loop and Iterator

Problems with For-Loop

There are some basic disadvantages to using the traditional For-loop when we want to deal with more complex data structures. Fortunately, with the Collections framework, Java introduced the use of an Iterator. An Iterator allows us to move through the elements of a data structure with several advantages over the traditional For-loop.
First, with iterator we don't have to worry about explicitly managing the movement of the index. With the For-loop, we need to specify the upper and lower bounds, and if a mistake is made our program will terminate with an IndexOutOfBoundsException.
Second, we can use the Iterator interface to move over several datatypes, even through those that don't have a natural ordering to them. For example, we can use an Iterator to display the contents of a HashMap.
Finally, the Iterator allows us to remove elements from the underlying collection simply, again saving us from having to worry about recalculating the loop bounds or the new index position.

Iterators are different from For-loop

We can perform lookup directly using index of element independent of position change in For-loop using index++. While in Iterators the lookup and position change are tightly coupled. The only way to look up an element is to call next, and that lookup advances the position. Instead, we should think of Java iterators as being between elements. When we call next, the iterator jumps over the next element, and it returns a reference to the element that it just passed.

The For-loop is in many ways similar to a while loop – in particular; it is pre-tested rather than post-tested, while in case of iterator it is post tested. It is most often used when a fixed number of iterations are required, with this number known in advance.

Concept of Removing Elements using Iterator

Problem: How to remove element from collection and to avoid unexpected results after deletion?
Solution: We can use iterator. Iterator.remove is the only safe way to modify a collection during iteration; the behavior is unspecified if the underlying collection is modified in any other way while the iteration is in progress.

An Iterator is an object that enables us to traverse through a collection, and to remove elements from the collection selectively, if desired. We get an Iterator for a collection by calling its iterator method.

The Iterator interface is:

The hasNext method returns true if the iteration has more elements, and the next method returns the next element in the iteration. The remove method removes from the underlying Collection the last element that was returned by next.

In many situations, that make sense—we need to see the element before we can decide that it is the one that should be removed. But if we want to remove an element in a particular position, we still need to skip past the element. For example, here is how you remove the first element in a collection of strings.

The remove method may be called only once per call to next and throws an exception if this rule is violated. There is a dependency between calls to the next and remove methods. It is illegal to call remove if it wasn't preceded by a call to next. If we try, an IllegalStateException is thrown.

If we want to remove two adjacent elements, we cannot simply call

it.remove();
it.remove(); // Error!

Instead, we must first call next to jump over the element to be removed.

it.remove();
it.next();
it.remove(); // Ok

Problem: Collections can be represented in many of forms. With such a variety of traversal mechanisms for different forms of collection, how can we hope to come up with a single generic method that will work for collections that are stored in wildly different forms?

Solution: This problem is solved by iterators. An iterator is an object that can be used to traverse a collection. Different types of collections have different types of iterators, but all iterators are used in the same way. An algorithm that uses an iterator to traverse a collection is generic, because the same technique can be applied to any type of collection.

Using iterators, we can write code for printing all the items in any collection. Suppose that coll is of type Collection. Then we can say:

Iterator iter = coll.iterator();
while ( iter.hasNext() ) {
Object item = iter.next();
System.out.println(item);
}

The same general form will work for other types of processing. For example, here is a subroutine that will remove all null values from any collection (as long as that collection supports removal of values):

void removeNullValues( Collection coll ) {
Iterator iter = coll.iterator():
while ( iter.hasNext() ) {
Object item = iter.next();
if (item == null)
iter.remove();
}
}

For-Each Construct : The Enhanced For-Loop

The for-each construct allows you to concisely traverse a collection or array using a for loop. The following code uses the for-each construct to print out each element of a collection on a separate line:

for (Object o : collection)
System.out.println(o);

Problem and Restrictions with the enhanced for loop

The syntax of the for(:) loop does not use an iterator for the collection.
CANNOT be used to remove elements from a collection. The 'for-each' loop hides the iterator, so you CANNOT call remove(). Therefore, the 'for-each' loop is not usable for filtering:

Example: JDOM element deletion from ElementList problem

JDOM element deletion from ElementList problemI have one XML file with multiple table elements like this. I am using Jdom for xml changes.

I want to delete the "table" elements which are having parentId="1″.
For deleting I am using the following code:

<!--[if gte vml 1]&gt; &lt;![endif]--><!--[if !vml]--><!--[endif]-->

tableList contains List of table Elementvalues.

But, I am getting the following result:

<!--[if gte vml 1]&gt; &lt;![endif]--><!--[if !vml]--><!--[endif]-->

Problem:Some of specified table elements are not deleted I think the problem is not with XML stuff but the loop iterating over a container is causing the problem. In loop, I am removing elements from the container, which in effect will shrink the size and hence will create possibilities to miss some locations.
Idiom: Do not remove items from a dynamic container while iterating over the same.
Solution: Use "Iterators" instead of the For-loop.

An Example of remove element using For-loop and Iterator

With all that data stored in our Array, we of course want some way to access that data. Using an Array inspector such as FetchItemAt() of course works, but there are times when we wish to walk our Array from one point to another, perhaps looking for a specific element or perhaps performing an operation on or with elements in the Array. This is where Iterators come in to play. An Iterator provides us with a means of sequentially traversing an Array. Again we could use a loop and FetchItemAt() to traverse our Array, but consider the following situation:

<!--[if gte vml 1]&gt; &lt;![endif]--><!--[if !vml]--><!--[endif]-->

What would happen in the above situation if targetData was found? It would of course be removed from the Array. After removing the item from the Array, the Array is now one less and numItems is no longer valid. When i == numItems, we could be in for some unexpected results! And if there happened to be more than one instance of targetData in the Array, we could be in for trouble a lot sooner. Instead, we can try using an Iterator:

<!--[if gte vml 1]&gt; &lt;![endif]--><!--[if !vml]--><!--[endif]-->

The two blocks of code perform the same function, but the latter version is savvier to the Array changing underneath it. The Iterators are not locked to certain numbers as the first example is, but rather to concepts such as "Next" and "Previous" to walk the Array. Additionally, an Array can have multiple Iterators.

Your Ad Here
#chitikatest=doctor