Showing posts with label Core Java. Show all posts
Showing posts with label Core Java. Show all posts

Wednesday 13 April 2016

Integer wrapper objects share the same instances only within the value 127

Since Java 5, wrapper class caching was introduced. The following is an examination of the cache created by an inner class, IntegerCache, located in the Integer cache. For example, the following code will create a cache:
Integer myNumber = 10
or
Integer myNumber = Integer.valueOf(10);
256 Integer objects are created in the range of -128 to 127 which are all stored in an Integer array. This caching functionality can be seen by looking at the inner class, IntegerCache, which is found in Integer:
So when creating an object using Integer.valueOf or directly assigning a value to an Integer within the range of -128 to 127 the same object will be returned. Therefore, consider the following example:
Integer i = 100;
Integer p = 100;
if (i == p)  
    System.out.println("i and p are the same.");
if (i != p)
    System.out.println("i and p are different.");   
if(i.equals(p))
    System.out.println("i and p contain the same value.");
The output is:
i and p are the same.
i and p contain the same value.
It is important to note that object i and p only equate to true because they are the same object, the comparison is not based on the value, it is based on object equality. If Integer i and p are outside the range of -128 or 127 the cache is not used, therefore new objects are created. When doing a comparison for value always use the “.equals” method. It is also important to note that instantiating an Integer does not create this caching.
Remember that “==” is always used for object equality, it has not been overloaded for comparing unboxed values

How to Retrieve Automatically Generated Keys in JDBC?

You can retrieve automatically generated keys (also called auto-generated keys or auto increment) from a table using JDBC 3.0 methods getGeneratedKeys(). The getGeneratedKeys()provide a standard way to make auto-generated or identity column values available to an application that is updating a database table without a requiring a query and a second round-trip to the server. SQL Server allows only a single auto increment column per table.
The ResultSet that is returned by getGeneratedKeys method will have only one column, with the returned column name of GENERATED_KEYS.
If generated keys are requested on a table that has no auto increment column, the JDBC driver will return a null result set.
When you insert rows by executeUpdate or execute an INSERT statement or an INSERT within SELECT statement, you need to indicate that you will want to retrieve automatically generated key values. You do that by setting a flag in a Connection.prepareStatement, Statement.executeUpdate, or Statement.execute method call. The statement that is executed must be an INSERT statement or an INSERT within SELECT statement. Otherwise, the JDBC driver ignores the parameter that sets the flag.

Monday 11 April 2016

Java Basic Quiz -1

Java Basic Quiz -1

Please select atleast one option
  1. Which one is thread safe ?

  2. ArrayList
    HashTable
    HashMap

  3. How many public class created in one java file ?

  4. 1
    2
    3

  5. Which of these method of class String is used to compare two String objects for their equality? ?

  6. Equals()
    equals()
    iseEqual()

  7. Standard output variable ‘out’ is defined in which class?

  8. Process
    Runtime
    System

  9. Which of the following is correct way of implementing an interface salary by class manager?

  10. class manager implements salary {}
    class manager imports salary {}
    class manager extends salary {}

If you have any doubt mail me : jpt112233@gmail.com

Friday 24 July 2015

Insert Image in database

Require Driver : mysql-connector-java-5.0.8-bin.jar


Table Structure : 

CREATE TABLE myImageFiles (
  id int(11) NOT NULL auto_increment,
  document blob
)

Thursday 4 June 2015

Evaluating a math expression given in string form

With JDK1.6, you can use the built-in Javascript engine.


The Java Scripting functionality is in the javax.script package. This is a relatively small, simple API. The starting point of the scripting API is the ScriptEngineManager class. A ScriptEngineManager object can discover script engines through the jar file service discovery mechanism. It can also instantiate ScriptEngine objects that interpret scripts written in a specific scripting language. The simplest way to use the scripting API is as follows:
  1. Create a ScriptEngineManager object.
  2. Get a ScriptEngine object from the manager.
  3. Evaluate script using the ScriptEngine's eval methods.

import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;

public class Test {
  public static void main(String[] args) throws Exception{
    ScriptEngineManager mgr = new ScriptEngineManager();
    ScriptEngine engine = mgr.getEngineByName("JavaScript");
    String foo = "40+2";
    System.out.println(engine.eval(foo));
    } 
}

Tuesday 5 May 2015

Externalizable vs Serializable

  • Externalizable is an interface that enables you to define custom rules and your own mechanism for serialization. Serializable defines standard protocol and provides out of the box serialization capabilities.
  • Externalizable extends Serializable.
  • Implement writeExternal and readExternal methods of the Externalizable interface and create your own contract / protocol for serialization.
  • Saving the state of the supertypes is responsibility of the implementing class.
  • You might have seen in my previouse article on how to customize the default implementation of Serializable. These two methods readExternal and writeExternal (Externalizable) supersedes this customized implementation of readObject and writeObject.
  • In object de-serialization (reconsturction) the public no-argument constructor is used to reconstruct the object. In case of Serializable, instead of using constructor, the object is re-consturcted using data read from ObjectInputStream.
  • The above point subsequently mandates that the Externalizable object must have a public no-argument constructor. In the case of Seriablizable it is not mandatory.
  • Behaviour of writeReplace and readResolve methods are same for both Serializable and Externalizable objects. writeReplace allows to nominate a replacement object to be written to the stream. readResolve method allows to designate a replacement object for the object just read from the stream.
  • In most real time scenarios, you can use Serializable and write your own custom implementation for serialization by providing readObject and writeObject.
  • You may need Externalizable,
    1. If you are not happy with the way java writes/reads objects from stream.
    2. Special handling for supertypes on object construction during serialization.

Wednesday 22 April 2015

Understanding Java Garbage Collection

What are the benefits of knowing how garbage collection (GC) works in Java? Satisfying the intellectual curiosity as a software engineer would be a valid cause, but also, understanding how GC works can help you write much better Java applications.

This is a very personal and subjective opinion of mine, but I believe that a person well versed in GC tends to be a better Java developer. If you are interested in the GC process, that means you have experience in developing applications of certain size. If you have thought carefully about choosing the right GC algorithm, that means you completely understand the features of the application you have developed. Of course, this may not be common standards for a good developer. However, few would object when I say that understanding GC is a requirement for being a great Java developer. 

This is the first of a series of "Become a Java GC Expert" articles. I will cover the GC introduction this time, and in the next article, I will talk about analyzing GC status and GC tuning examples from NHN.

The purpose of this article is to introduce GC to you in an easy way. I hope this article proves to be very helpful. Actually, my colleagues have already published a few great articles on Java Internals which became quite popular on Twitter. You may refer to them as well.
Returning back to Garbage Collection, there is a term that you should know before learning about GC. The term is "stop-the-world." Stop-the-world will occur no matter which GC algorithm you choose. Stop-the-world means that the JVM is stopping the application from running to execute a GC. When stop-the-world occurs, every thread except for the threads needed for the GC will stop their tasks. The interrupted tasks will resume only after the GC task has completed. GC tuning often means reducing this stop-the-world time.

Generational Garbage Collection 

Java does not explicitly specify a memory and remove it in the program code. Some people sets the relevant object to null or use System.gc() method to remove the memory explicitly. Setting it to null is not a big deal, but calling System.gc() method will affect the system performance drastically, and must not be carried out. (Thankfully, I have not yet seen any developer in NHN calling this method.)
In Java, as the developer does not explicitly remove the memory in the program code, the garbage collector finds the unnecessary (garbage) objects and removes them. This garbage collector was created based on the following two hypotheses. (It is more correct to call them suppositions or preconditions, rather than hypotheses.) 
  • Most objects soon become unreachable.
  • References from old objects to young objects only exist in small numbers.
These hypotheses are called the weak generational hypothesis. So in order to preserve the strengths of this hypothesis, it is physically divided into two - young generation and old generation - in HotSpot VM.

Young generation: Most of the newly created objects are located here. Since most objects soon become unreachable, many objects are created in the young generation, then disappear. When objects disappear from this area, we say a "minor GC" has occurred. 

Old generation: The objects that did not become unreachable and survived from the young generation are copied here. It is generally larger than the young generation. As it is bigger in size, the GC occurs less frequently than in the young generation. When objects disappear from the old generation, we say a "major GC" (or a "full GC") has occurred. 
Let's look at this in a chart.
Figure 1: GC Area & Data Flow.
Figure 1: GC Area & Data Flow.
The permanent generation from the chart above is also called the "method area," and it stores classes or interned character strings. So, this area is definitely not for objects that survived from the old generation to stay permanently. A GC may occur in this area. The GC that took place here is still counted as a major GC. 
Some people may wonder:
What if an object in the old generation need to reference an object in the young generation?
To handle these cases, there is something called the a "card table" in the old generation, which is a 512 byte chunk. Whenever an object in the old generation references an object in the young generation, it is recorded in this table. When a GC is executed for the young generation, only this card table is searched to determine whether or not it is subject for GC, instead of checking the reference of all the objects in the old generation. This card table is managed with write barrier. This write barrier is a device that allows a faster performance for minor GC. Though a bit of overhead occurs because of this, the overall GC time is reduced. 
Figure 2: Card Table Structure.
Figure 2: Card Table Structure.

Composition of the Young Generation

In order to understand GC, let's learn about the young generation, where the objects are created for the first time. The young generation is divided into 3 spaces. 
  • One Eden space
  • Two Survivor spaces
There are 3 spaces in total, two of which are Survivor spaces. The order of execution process of each space is as below:
  1. The majority of newly created objects are located in the Eden space.
  2. After one GC in the Eden space, the surviving objects are moved to one of the Survivor spaces. 
  3. After a GC in the Eden space, the objects are piled up into the Survivor space, where other surviving objects already exist.
  4. Once a Survivor space is full, surviving objects are moved to the other Survivor space. Then, the Survivor space that is full will be changed to a state where there is no data at all.
  5. The objects that survived these steps that have been repeated a number of times are moved to the old generation.
As you can see by checking these steps, one of the Survivor spaces must remain empty. If data exists in both Survivor spaces, or the usage is 0 for both spaces, then take that as a sign that something is wrong with your system.
The process of data piling up into the old generation through minor GCs can be shown as in the below chart:
Figure 3: Before & After a GC.
Figure 3: Before & After a GC.

Note that in HotSpot VM, two techniques are used for faster memory allocations. One is called "bump-the-pointer," and the other is called "TLABs (Thread-Local Allocation Buffers)." 
Bump-the-pointer technique tracks the last object allocated to the Eden space. That object will be located on top of the Eden space. And if there is an object created afterwards, it checks only if the size of the object is suitable for the Eden space. If the said object seems right, it will be placed in the Eden space, and the new object goes on top. 

So, when new objects are created, only the lastly added object needs to be checked, which allows much faster memory allocations. However, it is a different story if we consider a multithreaded environment. To save objects used by multiple threads in the Eden space for Thread-Safe, an inevitable lock will occur and the performance will drop due to the lock-contention. TLABs is the solution to this problem in HotSpot VM. 

This allows each thread to have a small portion of its Eden space that corresponds to its own share. As each thread can only access to their own TLAB, even the bump-the-pointer technique will allow memory allocations without a lock. 

This has been a quick overview of the GC in the young generation. You do not necessarily have to remember the two techniques that I have just mentioned. You will not go to jail for not knowing them. But please remember that after the objects are first created in the Eden space, and the long-surviving objects are moved to the old generation through the Survivor space.

GC for the Old Generation

The old generation basically performs a GC when the data is full. The execution procedure varies by the GC type, so it would be easier to understand if you know different types of GC. 
According to JDK 7, there are 5 GC types. 
  1. Serial GC
  2. Parallel GC
  3. Parallel Old GC (Parallel Compacting GC)
  4. Concurrent Mark & Sweep GC  (or "CMS")
  5. Garbage First (G1) GC
Among these, the serial GC must not be used on an operating server. This GC type was created when there was only one CPU core on desktop computers. Using this serial GC will drop the application performance significantly. 
Now let's learn about each GC type.

Serial GC (-XX:+UseSerialGC)

The GC in the young generation uses the type we explained in the previous paragraph. The GC in the old generation uses an algorithm called "mark-sweep-compact."
  1. The first step of this algorithm is to mark the surviving objects in the old generation.
  2. Then, it checks the heap from the front and leaves only the surviving ones behind (sweep).
  3. In the last step, it fills up the heap from the front with the objects so that the objects are piled up consecutively, and divides the heap into two parts: one with objects and one without objects (compact).
The serial GC is suitable for a small memory and a small number of CPU cores.

Parallel GC (-XX:+UseParallelGC)

Figure 4: Difference between the Serial GC and Parallel GC.
Figure 4: Difference between the Serial GC and Parallel GC.
From the picture, you can easily see the difference between the serial GC and parallel GC. While the serial GC uses only one thread to process a GC, the parallel GC uses several threads to process a GC, and therefore, faster. This GC is useful when there is enough memory and a large number of cores. It is also called the "throughput GC." 

Parallel Old GC(-XX:+UseParallelOldGC)

Parallel Old GC was supported since JDK 5 update. Compared to the parallel GC, the only difference is the GC algorithm for the old generation. It goes through three steps: mark – summary – compaction. The summary step identifies the surviving objects separately for the areas that the GC have previously performed, and thus different from the sweep step of the mark-sweep-compact algorithm. It goes through a little more complicated steps.

CMS GC (-XX:+UseConcMarkSweepGC)

Figure 5: Serial GC & CMS GC.
Figure 5: Serial GC & CMS GC.
As you can see from the picture, the Concurrent Mark-Sweep GC is much more complicated than any other GC types that I have explained so far. The early initial mark step is simple. The surviving objects among the objects the closest to the classloader are searched. So, the pausing time is very short. In the concurrent mark step, the objects referenced by the surviving objects that have just been confirmed are tracked and checked. The difference of this step is that it proceeds while other threads are processed at the same time. In the remark step, the objects that were newly added or stopped being referenced in the concurrent mark step are checked. Lastly, in the concurrent sweep step, the garbage collection procedure takes place. The garbage collection is carried out while other threads are still being processed. Since this GC type is performed in this manner, the pausing time for GC is very short. The CMS GC is also called the low latency GC, and is used when the response time from all applications is crucial
While this GC type has the advantage of short stop-the-world time, it also has the following disadvantages.
  • It uses more memory and CPU than other GC types.
  • The compaction step is not provided by default.
You need to carefully review before using this type. Also, if the compaction task needs to be carried out because of the many memory fragments, the stop-the-world time can be longer than any other GC types. You need to check how often and how long the compaction task is carried out.

G1 GC

Finally, let's learn about the garbage first (G1) GC. 
Figure 6: Layout of G1 GC.
Figure 6: Layout of G1 GC.
If you want to understand G1 GC, forget everything you know about the young generation and the old generation. As you can see in the picture, one object is allocated to each grid, and then a GC is executed. Then, once one area is full, the objects are allocated to another area, and then a GC is executed. The steps where the data moves from the three spaces of the young generation to the old generation cannot be found in this GC type. This type was created to replace the CMS GC, which has causes a lot of issues and complaints in the long term.
The biggest advantage of the G1 GC is its performance. It is faster than any other GC types that we have discussed so far. But in JDK 6, this is called an early access and can be used only for a test. It is officially included in JDK 7. In my personal opinion, we need to go through a long test period (at least 1 year) before NHN can use JDK7 in actual services, so you probably should wait a while. Also, I heard a few times that a JVM crash occurred after applying the G1 in JDK 6. Please wait until it is more stable.
I will talk about the GC tuning in the next issue, but I would like to ask you one thing in advance. If the size and the type of all objects created in the application are identical, all the GC options for WAS used in our company can be the same. But the size and the lifespan of the objects created by WAS vary depending on the service, and the type of equipment varies as well. In other words, just because a certain service uses the GC option "A," it does not mean that the same option will bring the best results for a different service. It is necessary to find the best values for the WAS threads, WAS instances for each equipment and each GC option by constant tuning and monitoring. This did not come from my personal experience, but from the discussion of the engineers making Oracle JVM for JavaOne 2010.
In this issue, we have only glanced at the GC for Java. Please look forward to our next issue, where I will talk about how to monitor the Java GC status and tune GC
I would like to note that I referred to a new book released in December 2011 called "Java Performance" (Amazon, it can also be viewed from safari online, if the company provides an account), as well as “Memory Management in the Java HotSpotTM Virtual Machine,” a white paper provided by the Oracle website. (The book is different from "Java Performance Tuning.")
By Sangmin Lee, Senior Engineer at Performance Engineering Lab, NHN Corporation.

Sunday 24 August 2014

Java : Drawing the shape of the detected object?

After detecting the people upperbody rect:
  1. Remove the rect background, keeping just the person upperbody.
  2. Binarize the image.
  3. Apply morphological boundary algorithm to trace the upperbody.
Example:
enter image description here
OpenCV provides these algorithms. However, the example above was developed using Marvin. The source code is presented below:
public class TraceShape {

    public TraceShape(){
        // Load Plug-in
        MarvinImagePlugin boundary = MarvinPluginLoader.loadImagePlugin( 
        "org.marvinproject.image.morphological.boundary");

        // Load image
        MarvinImage image = MarvinImageIO.loadImage("./res/person.jpg");

        // Binarize
        MarvinImage binImage = MarvinColorModelConverter.rgbToBinary(image, 245);
        MarvinImageIO.saveImage(binImage, "./res/person_bin.png");

        // Boundary
        boundary.process(binImage.clone(), binImage);
        MarvinImageIO.saveImage(binImage, "./res/person_boundary.png");
    }

    public static void main(String[] args) {
        new TraceShape();
    }
}

Thursday 21 August 2014

Java : MultiKeyMap Example

  •  A Map implementation that uses multiple keys to map the value.
  • This class is the most efficient way to uses multiple keys to map to a value. The best way to use this class is via the additional map-style methods. These provide get, containsKey, put and remove for individual keys which operate without extra object creation.
  • The additional methods are the main interface of this map. As such, you will not normally hold this map in a variable of type Map.
  • The normal map methods take in and return a MultiKey. If you try to use put() with any other object type a ClassCastException is thrown. If you try to use null as the key in put() a NullPointerException is thrown.
  • This map is implemented as a decorator of a AbstractHashedMap which enables extra behaviour to be added easily.
    •  MultiKeyMap.decorate(new LinkedMap()) creates an ordered map
    •  MultiKeyMap.decorate(new LRUMap()) creates an least recently used map.
    • MultiKeyMap.decorate(new ReferenceMap()) creates a garbage collector sensitive map. 
  • Note that IdentityMap and ReferenceIdentityMap are unsuitable for use as the key comparison would work on the whole MultiKey, not the elements within.
  • Note that MultiKeyMap is not synchronized and is not thread-safe. If you wish to use this map from multiple threads concurrently, you must use appropriate synchronization. This class may throw exceptions when accessed by concurrent threads without synchronization.
  • Apache Commons Collections to create a MultiKeyMap that will store two keys with one corresponding value and then using MapIterator to walk through the map.
  • MultiKeyMap keys are instances of MultiKey, which has a getKey(int index) method. There is also a getKeys() method which returns Object[].

Wednesday 9 July 2014

How to get IP address in Java using InetAddress

An Internet Protocol address (IP address) is a numerical label assigned to each device (e.g., computer, printer) participating in a computer network that uses the Internet Protocol for communication. The designers of the Internet Protocol defined an IPv4 address as a 32-bit number.
In this tutorial we are going to see how can you get the IP Address that is assigned to your own machine inside your local network and the IP Addresses assigned to specific Domain Names(e.g. www.google.com…).
To do that we are going to use InetAddress.To be more specific we are going to use:
  • getLocalHost().getHostAddress() method of InetAddress to get the IP Address of our machine in our local network
  • getByName() method of InetAddress to get the IP Address of a specific Domain Name
  • getAllByName() method of InetAddress to get all the IP Address of a specific Domain Name.

Thursday 22 May 2014

Merging two images

Just create a new BufferedImage with transparency, then paint the other two images (with full or semi-transparency) on it. This is how it will look like:
combining images
Sample code (images are called 'image.png' and 'overlay.png'):
File path = ... // base path of the images

// load source images
BufferedImage image = ImageIO.read(new File(path, "image.png"));
BufferedImage overlay = ImageIO.read(new File(path, "overlay.png"));

// create the new image, canvas size is the max. of both image sizes
int w = Math.max(image.getWidth(), overlay.getWidth());
int h = Math.max(image.getHeight(), overlay.getHeight());
BufferedImage combined = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

// paint both images, preserving the alpha channels
Graphics g = combined.getGraphics();
g.drawImage(image, 0, 0, null);
g.drawImage(overlay, 0, 0, null);

// Save as new image
ImageIO.write(combined, "PNG", new File(path, "combined.png"));

Friday 25 April 2014

Rotate Cross Lines With help Of Circle


                             

                                double radians = Math.atan2(event.getY() - osPoint.getCenterY(), event.getX()
- osPoint.getCenterX());

double degrees = Math.round((radians * 180 / Math.PI));

double rotation = degrees + 90;

osPoint.setRotate(osPoint.getRotate() + rotation);
osHline.setRotate(osHline.getRotate() + rotation);
osVline.setRotate(osVline.getRotate() + rotation);

Tuesday 15 April 2014

java replaceFirst problem with $

Not here, it isn't. When calling replaceFirst() or replaceAll(), the first argument is a regular expression, which follows the rules of java regular expressions as described in java.util.regex.Pattern. But the second argument is not a regex; it's a replacement text - which has different rules. Quoting from the String.replaceFirst() API: "Note that backslashes (\) and dollar signs ($) in the replacement string may cause the results to be different than if it were being treated as a literal replacement string; see Matcher.replaceFirst(java.lang.String). Use Matcher.quoteReplacement(java.lang.String) to suppress the special meaning of these characters, if desired."

If you follow the link to Matcher.replaceFirst() it refers you to Matcher.appendReplacement() which has more detail: "The replacement string may contain references to subsequences captured during the previous match: Each occurrence of $g will be replaced by the result of evaluating group(g). The first number after the $ is always treated as part of the group reference. Subsequent numbers are incorporated into g if they would form a legal group reference. Only the numerals '0' through '9' are considered as potential components of the group reference. If the second group matched the string "foo", for example, then passing the replacement string "$2bar" would cause "foobar" to be appended to the string buffer. A dollar sign ($) may be included as a literal in the replacement string by preceding it with a backslash (\$)."

In other words, $1 would be capture group 1, $6 would be capture group 6. $z doesn't make sense to the matcher - that's what "Illegal group reference" means here. Because z is not a group.

And to fix this problem, you can either do as EFJ showed, putting a double backslash in front of the $, or you can use Matcher.quoteReplacement() as suggested in the replaceFirst() API:

String y = Matcher.quoteReplacement("xy$z");


Now What we do in this case : String x ="${data} m,.m,.m,";

So the solution is :


        String x ="${data} m,.m,.m,";
        String y = x.replaceFirst("\\$\\{data\\}", "Amaan");
        System.out.println(y); 

Sunday 23 March 2014

Delete particular folder base don Time Criteria

package Bean;

import java.io.File;
import java.util.Calendar;

public class DeleteDir {

    private static void autoDeleteFileAndDir(String filePath, Integer hours,
            Integer minutes) {
        Long timeDiff;
        if (filePath != null && !filePath.isEmpty()
                && (hours != null || minutes != null)) {
            if(hours!=null&&hours>0){
                timeDiff= (long) (hours*60 * 60 * 1000);
            }else {
                timeDiff= (long) (minutes * 60 * 1000);
            }
           
            File file = new File(filePath);

            System.out
            .println("Now will search folders and delete files in :: ,\nFile path :: "
                    + file.getAbsolutePath());
           
            if (file.isDirectory()) {
                for (File f : file.listFiles()) {
                    if (f.isDirectory()) {
                        Long FileTimeDiff = (Calendar.getInstance().getTime().getTime() - f
                                .lastModified());
                       
                        System.out.println("\n\nf.lastModified() :: "
                                + f.lastModified()
                                + "\nnew Date().getDate() :: "
                                + Calendar.getInstance().getTime().getTime() + "\nDiff :: "
                                + FileTimeDiff);
                       
                        if (FileTimeDiff > timeDiff) {
                            if (f.delete()) {
                       
                                System.out.println("\n\n" + f.getName()
                                        + ":: Dir deleted!!!!!");
                               
                            }
                        } else {
                           
                            System.out.println("\n\n" + f.getName()
                                    + ":: Dir not deleted!!!!!");
                           
                        }
                    }
                }
            }
           
        }else {
            System.out.println("Invalid parameter");
        }
       
    }

Monday 27 January 2014

How much memory do Enums take?

Java programming language enum types are much more powerful than their counterparts in other languages. The enum declaration defines a class (called an enum type). The enum class body can include methods and other fields.
In order to see the actual size of each enum, let's make an actual enum and examine the contents of the class file it creates.
Let's say we have the following Constants enum class:
public enum Constants {
  ONE,
  TWO,
  THREE;
}
Compiling the above enum and disassembling resulting class file with javap gives the following:
Compiled from "Constants.java"
public final class Constants extends java.lang.Enum{
    public static final Constants ONE;
    public static final Constants TWO;
    public static final Constants THREE;
    public static Constants[] values();
    public static Constants valueOf(java.lang.String);
    static {};
}
The disassembly shows that that each field of an enum is an instance of the Constants enum class. (Further analysis with javap will reveal that each field is initialized by creating a new object by calling the new Constants(String) constructor in the static initialization block.)
Therefore, we can tell that each enum field that we create will be at least as much as the overhead of creating an object in the JVM.

ZIP and UNZIP with Passwords in Java

Zip and Unzip are a very common activities for a computer user. A user normally uses the zip utility to compress a directory to create a zip file. There are many ready-made software such as winzip,7zip, and winrar that are available to achieve this. 

However, it is also possible to protect the zip file with a password so that the end user has to provide the password to unzip the zip file. This is the very common scenario that can be achieved by a zip utility tool. The significant part of my article is to provide you with the solution to achieve this using a Java program. While developing the project you may encounter a scenario in which you have to create a password-protected zip file that can be unzipped by any zip tool like winzip. Let me provide a complete scenario for your understanding.

In a system, some files are generated for a user and all the files are zipped with a password. The generated password protected zip file is sent to the user through email and the password for the zip file to open is sent to the particular user as an SMS to the user's mobile. 

 Similarly the end-user creates a password protected zip file and uploads to a online system with the user's password in a text field. In this case we have to develop a system where the system will be able to create a password protected zip file and should be able to extract all the files from a password protected zip file. Let me show you how you can achieve it.

Technicalities
However, Java provides the feature of creating a zip file and also provides the feature to unzip or decompress a zip file. But there is no default java API to create a password protected zip file and also there is no default java API to unzip a password protected zip file. To facilitate this feature of zip utility some developers have developed java API in this regard. We have to use their API to achieve this. We have to look into the following aspects of zip utility.
  1. Java-enabled system should be able to generate a password protected zip file and that password protected zip file can be unzipped by any zip utility like winzip and others
  2. Java-enabled system should be able to decompress or unzip a password protected zip file created by any zip utility like winzip and others.
The followings are the APIs you have to use for this objective:

1.To create a password protected zip file in java, you have to use “winzipaes”. It is avilable in Google code. You can download the .jar file and the source code from the following link.

This API helps to add a password to a already created zip file. It means that if you want to create a password protected zip file, first you have to create a zip file and then you can add a password that zip file. It is a pure java API works with any operating system. You have to download the following jar file from the above URL.

passwordcompressor.jar

2.To unzip or decompress a password protected zip file, you have to use “sevenzipjbind”. It is available in sourceforge.net site. You can download the .jar files from the following link: http://sourceforge.net/projects/sevenzipjbind/files/. This API helps to extract all the files and folders from password protected zip file created by any zip utility tool. You have to download the following .jar files from the above URL.
sevenzipjbinding-AllPlatforms.jar
sevenzipjbinding.jar

3.For password protection, you have to use Bouncecastle cryptographic API. You can download the .jar file from the following link.
http://www.bouncycastle.org/
You have to download the following .jar files from the above URL.
bcprov-jdk15-145.jar

After downloading all the .jar files, put all the .jar files in your classpath. I have written a java program by using all these APIs to achieve all the above mentioned functionalities.
Have a look at the following code structure.

Code for ZipUtil.java


Saturday 25 January 2014

DicomMultiframePlayer in JAVA

package packageTestDcm4che3;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Vector;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;

import javax.imageio.ImageReader;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.FileImageInputStream;
import javax.imageio.stream.ImageInputStream;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import org.dcm4che.imageio.plugins.dcm.DicomImageReadParam;
import org.dcm4che.imageio.plugins.dcm.DicomImageReader;

/**
 * Plays a multiframe DICOM instance.
 *
 * @author dimitri PIANETA
 *
 * <p>The code for this came from <a href="http://samucs.blogspot.com" target="_blank">http://samucs.blogspot.com</a>
 *    and was dated 6-January-2010.</p>
 *
 * <p> code modification 14 January 2014 for dcm4che3 <p>
 */   
public class DicomMultiframePlayer extends JFrame implements ActionListener, Runnable {
   
    private static final long serialVersionUID = 1L;
    private JLabel fileLabel;
    /**
     * Will contain name of file to be read.
     */
    private JTextField fileField;
    /**
     * Triggers process for selecting file to be read.
     * @see #actionPerformed(ActionEvent)
     */
    private JButton btnChoose;
    /**
     * Starts playing of images.
     * @see #actionPerformed(ActionEvent)
     */
    private JButton btnPlay;
    /**
     * Pauses playing of images.
     * @see #actionPerformed(ActionEvent)
     */
    private JButton btnPause;
    /**
     * Halts playing of images.
     * @see #actionPerformed(ActionEvent)
     */
    private JButton btnStop;
    private JButton btnExit;   
    private Vector<BufferedImage> images;
    private ImagePanel imagePanel;   
    private boolean stop;
    private int currentFrame;
   
       
        private int frame = 1;

       
       
       
          private final ImageReader imageReader =
            ImageIO.getImageReadersByFormatName("DICOM").next();
       
       
    public DicomMultiframePlayer() {
        super("DICOM Multiframe Player using dcm4che - by samucs-dev");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.getContentPane().setLayout(new BorderLayout());
       
        images = new Vector<BufferedImage>();
        imagePanel = new ImagePanel();
       
        fileLabel = new JLabel("File:");
        fileField = new JTextField(30);
        btnChoose = this.createJButton(25, 25, "...");
       
        btnPlay = this.createJButton(80,25,"Play");
        btnPause = this.createJButton(80,25,"Pause");
        btnStop = this.createJButton(80,25,"Stop");       
        btnExit = this.createJButton(80,25,"Exit");
        btnPause.setEnabled(false);
        btnStop.setEnabled(false);
       
        JPanel panelNorth = new JPanel();
        panelNorth.add(fileLabel);
        panelNorth.add(fileField);
        panelNorth.add(btnChoose);
       
        JPanel panelSouth = new JPanel();
        panelSouth.add(btnPlay);
        panelSouth.add(btnPause);
        panelSouth.add(btnStop);
        panelSouth.add(btnExit);
       
        this.getContentPane().add(panelNorth, BorderLayout.NORTH);
        this.getContentPane().add(imagePanel, BorderLayout.CENTER);
        this.getContentPane().add(panelSouth, BorderLayout.SOUTH);
       
        this.setSize(new Dimension(500,500));
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }
    /**
     * Plays the frames in order.
     *
     * <p>I removed the Override annotation.</p>
     */
    // @Override
    public void run() {
        while(true) {
            if (!btnPlay.isEnabled()) {               
                if (stop) break;               
                currentFrame++;
                if (currentFrame == images.size())
                    currentFrame = 0;
                imagePanel.setImage(images.get(currentFrame));               
                try {
                    Thread.sleep(70);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    /**
     * Detects clicking of button and carries out appropriate action.
     *
     * <p>I removed the Override annotation.</p>
     */
    // @Override
    public void actionPerformed(ActionEvent e) {       
        if (e.getSource().equals(btnChoose)) {
            JFileChooser chooser = new JFileChooser();
            int action = chooser.showOpenDialog(this);
            switch(action) {
                case JFileChooser.APPROVE_OPTION:
                    this.openFile(chooser.getSelectedFile());
                    break;
                case JFileChooser.CANCEL_OPTION:
                    return;
            }
        }       
        if (e.getSource().equals(btnPlay)) {
            btnPlay.setEnabled(false);
            btnPause.setEnabled(true);
            btnStop.setEnabled(true);
            stop = false;
            new Thread(this).start();           
        }
        if (e.getSource().equals(btnPause)) {
            btnPlay.setEnabled(true);
            btnPause.setEnabled(false);
            btnStop.setEnabled(true);
            stop = false;
        }
        if (e.getSource().equals(btnStop)) {
            btnPlay.setEnabled(true);
            btnPause.setEnabled(false);
            btnStop.setEnabled(false);
            stop = true;
            currentFrame = 0;
            imagePanel.setImage(images.get(0));           
        }
        if (e.getSource().equals(btnExit)) {
            System.exit(0);
        }
    }
    /**
     * Creates JButton objects on window.
     * @param width width of button in pixels.
     * @param height height of button in pixels
     * @param text text to appear in button
     * @return JButton object
     */
    private JButton createJButton(int width, int height, String text) {
        JButton b = new JButton(text);
        b.setMinimumSize(new Dimension(width, height));
        b.setMaximumSize(new Dimension(width, height));
        b.setPreferredSize(new Dimension(width, height));
        b.addActionListener(this);
        return b;
    }
    /**
     * Reads the contents of the dicom file
     * @param file file to be opened
     * @see org.dcm4che2.imageioimpl.plugins.dcm.DicomImageReaderSpi
     * @see org.dcm4che2.imageioimpl.plugins.dcm.DicomImageReader
     */
    private void openFile(File file) {
        images.clear();
        try {
           
                   
                       
            int numFrames =setNumber(file);
            //System.out.println("DICOM image has "+ numFrames +" frames...");           
            System.out.println("Extracting frames...");
            for (int i=0; i < numFrames; i++) {
                     
                       
                          
                BufferedImage img =  chargeImageDicomBufferise(file,i);
                images.add(img);
                System.out.println(" > Frame "+ (i+1));
            }           
            System.out.println("Finished.");
        } catch(Exception e) {
            e.printStackTrace();
            imagePanel.setImage(null);
            return;
        }
        stop = false;
        currentFrame = 0;
        imagePanel.setImage(images.get(0));
    }

     
       
        /**
         * Building BufferingImage
         * @param file : input file
         * @param value : number frame
         * @return
         * @throws IOException
         */
       
        public BufferedImage chargeImageDicomBufferise(File file, int value) throws IOException  {

                Iterator<ImageReader> iter = ImageIO.getImageReadersByFormatName("DICOM");//sp?cifie l'image

                              
                         

              ImageReader readers = iter.next();//on se d?place dans l'image dicom

         DicomImageReadParam   param1 =  (DicomImageReadParam) readers.getDefaultReadParam();//return DicomImageReadParam
               //    Adjust the values of Rows and Columns in it and add a Pixel Data attribute with the byte array from the DataBuffer of the scaled Raster

                ImageInputStream iis = ImageIO.createImageInputStream(file);

             readers.setInput(iis, false);//sets the input source to use the given ImageInputSteam or other  Object

               BufferedImage image = readers.read(value,param1);//BufferedImage image = reader.read(frameNumber, param); frameNumber = int qui est l'imageIndex
                System.out.println(image);//affichage au terminal des caract?res de l'image

                readers.dispose();//Releases all of the native sreen resources used by this Window, its subcomponents, and all of its owned children
              return  image;

            }
   
         /**
 *  Find number frame
 * @param file : input file
 * @return numbre frame in Dicom
 * @throws IOException
 */
   public int setNumber(File file) throws IOException  {

            /* Parcourt le fichier dicom*/
             Iterator<ImageReader> iter = ImageIO.getImageReadersByFormatName("DICOM");//sp?cifie l'image
           ImageReader readers = (ImageReader)iter.next();//on se d?place dans l'image dicom

            DicomImageReadParam   param1=  (DicomImageReadParam) readers.getDefaultReadParam();//return DicomImageReadParam
           //    Adjust the values of Rows and Columns in it and add a Pixel Data attribute with the byte array from the DataBuffer of the scaled Raster

            ImageInputStream iis = ImageIO.createImageInputStream(file);//cr?ation du fichier image


           readers.setInput(iis, false);//sets the input source to use the given ImageInputSteam or other  Object

            //iis.close();
            int  number = readers.getNumImages(true);//numberOfFrame on a "readers" qui doit ?tre DicomImage
            System.out.println(number);//return NumberOfFrame (Tag : (0028, 0008))
           return  number;
        }
   
   
   
    private class ImagePanel extends JPanel {
        private static final long serialVersionUID = 1L;
        private BufferedImage image;
        private int frame;
        public ImagePanel() {
            super();
            this.setPreferredSize(new Dimension(1024,1024));
            this.setBackground(Color.black);           
        }
        public void setImage(BufferedImage image) {
            this.image = image;
            this.updateUI();
        }
        @Override
        public void paint(Graphics g) {
            if (this.image != null) {
                g.drawImage(this.image, 0, 0, image.getWidth(), image.getHeight(), null);
            }
        }
   
        };

    public static void main(String[] args) {
        new DicomMultiframePlayer();
    }

}