diff --git a/xstream-introduction/.classpath b/xstream-introduction/.classpath
new file mode 100644
index 0000000000..138df490af
--- /dev/null
+++ b/xstream-introduction/.classpath
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xstream-introduction/.project b/xstream-introduction/.project
new file mode 100644
index 0000000000..cebf3c9cfa
--- /dev/null
+++ b/xstream-introduction/.project
@@ -0,0 +1,14 @@
+
+
+ xstream-introduction
+ An Introduction To XStream. NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse.
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
\ No newline at end of file
diff --git a/xstream-introduction/pom.xml b/xstream-introduction/pom.xml
new file mode 100644
index 0000000000..2f0f26d6f2
--- /dev/null
+++ b/xstream-introduction/pom.xml
@@ -0,0 +1,30 @@
+
+ 4.0.0
+ org.baeldung
+ xstream-introduction
+ 0.0.1-SNAPSHOT
+ xstream-introduction
+ An Introduction To XStream
+
+
+
+ com.thoughtworks.xstream
+ xstream
+ 1.4.5
+
+
+
+ junit
+ junit
+ 4.12
+
+
+
+ log4j
+ log4j
+ 1.2.17
+
+
+
+
\ No newline at end of file
diff --git a/xstream-introduction/src/main/java/org/baeldung/initializer/SimpleXstreamInitializer.java b/xstream-introduction/src/main/java/org/baeldung/initializer/SimpleXstreamInitializer.java
new file mode 100644
index 0000000000..c96392daf5
--- /dev/null
+++ b/xstream-introduction/src/main/java/org/baeldung/initializer/SimpleXstreamInitializer.java
@@ -0,0 +1,19 @@
+package org.baeldung.initializer;
+
+import com.thoughtworks.xstream.XStream;
+
+public class SimpleXstreamInitializer {
+
+ private static XStream xtreamInstance;
+
+ public static XStream getXstreamInstance() {
+ if (xtreamInstance == null) {
+ synchronized (SimpleXstreamInitializer.class) {
+ if (xtreamInstance == null) {
+ xtreamInstance = new XStream();
+ }
+ }
+ }
+ return xtreamInstance;
+ }
+}
\ No newline at end of file
diff --git a/xstream-introduction/src/main/java/org/baeldung/pojo/AddressDetails.java b/xstream-introduction/src/main/java/org/baeldung/pojo/AddressDetails.java
new file mode 100644
index 0000000000..16930cb8ab
--- /dev/null
+++ b/xstream-introduction/src/main/java/org/baeldung/pojo/AddressDetails.java
@@ -0,0 +1,40 @@
+package org.baeldung.pojo;
+
+import java.util.List;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+
+@XStreamAlias("AddressDetails")
+public class AddressDetails {
+
+ private String address;
+
+ private String zipcode;
+
+ private List contactDetails;
+
+ public String getZipcode() {
+ return zipcode;
+ }
+
+ public void setZipcode(String zipcode) {
+ this.zipcode = zipcode;
+ }
+
+ public List getContactDetails() {
+ return contactDetails;
+ }
+
+ public void setContactDetails(List contactDetails) {
+ this.contactDetails = contactDetails;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+}
diff --git a/xstream-introduction/src/main/java/org/baeldung/pojo/ContactDetails.java b/xstream-introduction/src/main/java/org/baeldung/pojo/ContactDetails.java
new file mode 100644
index 0000000000..1cb353414b
--- /dev/null
+++ b/xstream-introduction/src/main/java/org/baeldung/pojo/ContactDetails.java
@@ -0,0 +1,28 @@
+package org.baeldung.pojo;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+
+@XStreamAlias("ContactDetails")
+public class ContactDetails {
+
+ private String mobile;
+
+ private String landline;
+
+ public String getMobile() {
+ return mobile;
+ }
+
+ public void setMobile(String mobile) {
+ this.mobile = mobile;
+ }
+
+ public String getLandline() {
+ return landline;
+ }
+
+ public void setLandline(String landline) {
+ this.landline = landline;
+ }
+
+}
diff --git a/xstream-introduction/src/main/java/org/baeldung/pojo/Customer.java b/xstream-introduction/src/main/java/org/baeldung/pojo/Customer.java
new file mode 100644
index 0000000000..aeb6e0aaf3
--- /dev/null
+++ b/xstream-introduction/src/main/java/org/baeldung/pojo/Customer.java
@@ -0,0 +1,55 @@
+package org.baeldung.pojo;
+
+import java.util.Date;
+import java.util.List;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamImplicit;
+import com.thoughtworks.xstream.annotations.XStreamOmitField;
+
+@XStreamAlias("customer")
+public class Customer {
+
+ @XStreamOmitField
+ private String firstName;
+
+ private String lastName;
+
+ private Date dob;
+
+ @XStreamImplicit
+ private List contactDetailsList;
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public Date getDob() {
+ return dob;
+ }
+
+ public void setDob(Date dob) {
+ this.dob = dob;
+ }
+
+ public List getContactDetailsList() {
+ return contactDetailsList;
+ }
+
+ public void setContactDetailsList(List contactDetailsList) {
+ this.contactDetailsList = contactDetailsList;
+ }
+
+}
diff --git a/xstream-introduction/src/main/java/org/baeldung/pojo/CustomerAddressDetails.java b/xstream-introduction/src/main/java/org/baeldung/pojo/CustomerAddressDetails.java
new file mode 100644
index 0000000000..e4ce5ae5cd
--- /dev/null
+++ b/xstream-introduction/src/main/java/org/baeldung/pojo/CustomerAddressDetails.java
@@ -0,0 +1,50 @@
+package org.baeldung.pojo;
+
+import java.util.List;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+
+@XStreamAlias("CustomerAddressDetails")
+public class CustomerAddressDetails {
+
+ private List addressDetails;
+
+ private String firstName;
+
+ private String lastName;
+
+ private int age;
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+
+ public List getAddressDetails() {
+ return addressDetails;
+ }
+
+ public void setAddressDetails(List addressDetails) {
+ this.addressDetails = addressDetails;
+ }
+}
diff --git a/xstream-introduction/src/main/java/org/baeldung/pojo/CustomerPortfolio.java b/xstream-introduction/src/main/java/org/baeldung/pojo/CustomerPortfolio.java
new file mode 100644
index 0000000000..cc65128650
--- /dev/null
+++ b/xstream-introduction/src/main/java/org/baeldung/pojo/CustomerPortfolio.java
@@ -0,0 +1,20 @@
+package org.baeldung.pojo;
+
+import java.util.List;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+
+@XStreamAlias("CustomerPortfolio")
+public class CustomerPortfolio {
+
+ private List customerAddressDetailsList;
+
+ public List getCustomerAddressDetailsList() {
+ return customerAddressDetailsList;
+ }
+
+ public void setCustomerAddressDetailsList(List customerAddressDetailsList) {
+ this.customerAddressDetailsList = customerAddressDetailsList;
+ }
+
+}
diff --git a/xstream-introduction/src/main/java/org/baeldung/utility/MyDateConverter.java b/xstream-introduction/src/main/java/org/baeldung/utility/MyDateConverter.java
new file mode 100644
index 0000000000..a11b58bd12
--- /dev/null
+++ b/xstream-introduction/src/main/java/org/baeldung/utility/MyDateConverter.java
@@ -0,0 +1,40 @@
+package org.baeldung.utility;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import com.thoughtworks.xstream.converters.ConversionException;
+import com.thoughtworks.xstream.converters.Converter;
+import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+
+public class MyDateConverter implements Converter {
+
+ private SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
+
+ @Override
+ public boolean canConvert(Class clazz) {
+ return Date.class.isAssignableFrom(clazz);
+ }
+
+ @Override
+ public void marshal(Object value , HierarchicalStreamWriter writer , MarshallingContext arg2) {
+ Date date = (Date) value;
+ writer.setValue(formatter.format(date));
+ }
+
+ @Override
+ public Object unmarshal(HierarchicalStreamReader reader , UnmarshallingContext arg1) {
+ GregorianCalendar calendar = new GregorianCalendar();
+ try {
+ calendar.setTime(formatter.parse(reader.getValue()));
+ } catch (ParseException e) {
+ throw new ConversionException(e.getMessage() , e);
+ }
+ return calendar;
+ }
+}
diff --git a/xstream-introduction/src/main/java/org/baeldung/utility/MySingleValueConverter.java b/xstream-introduction/src/main/java/org/baeldung/utility/MySingleValueConverter.java
new file mode 100644
index 0000000000..0cabc4fe03
--- /dev/null
+++ b/xstream-introduction/src/main/java/org/baeldung/utility/MySingleValueConverter.java
@@ -0,0 +1,29 @@
+package org.baeldung.utility;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.baeldung.pojo.Customer;
+
+import com.thoughtworks.xstream.converters.SingleValueConverter;
+
+public class MySingleValueConverter implements SingleValueConverter {
+
+ @Override
+ public boolean canConvert(Class clazz) {
+ return Customer.class.isAssignableFrom(clazz);
+ }
+
+ @Override
+ public Object fromString(String arg0) {
+ return null;
+ }
+
+ @Override
+ public String toString(Object obj) {
+ SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
+ Date date = ((Customer) obj).getDob();
+ return ((Customer) obj).getFirstName() + "," + ((Customer) obj).getLastName() + "," + formatter.format(date);
+ }
+
+}
diff --git a/xstream-introduction/src/main/java/org/baeldung/utility/SimpleDataGeneration.java b/xstream-introduction/src/main/java/org/baeldung/utility/SimpleDataGeneration.java
new file mode 100644
index 0000000000..e6a97e5ea6
--- /dev/null
+++ b/xstream-introduction/src/main/java/org/baeldung/utility/SimpleDataGeneration.java
@@ -0,0 +1,37 @@
+package org.baeldung.utility;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+import org.baeldung.pojo.ContactDetails;
+import org.baeldung.pojo.Customer;
+
+public class SimpleDataGeneration {
+
+ public static Customer generateData() {
+ Customer customer = new Customer();
+ Calendar cal = Calendar.getInstance();
+ cal.set(1986 , 01 , 14);
+ customer.setDob(cal.getTime());
+ customer.setFirstName("Xstream");
+ customer.setLastName("Java");
+
+ List contactDetailsList = new ArrayList();
+
+ ContactDetails contactDetails1 = new ContactDetails();
+ contactDetails1.setLandline("0124-2460311");
+ contactDetails1.setMobile("6673543265");
+
+ ContactDetails contactDetails2 = new ContactDetails();
+ contactDetails2.setLandline("0120-223312");
+ contactDetails2.setMobile("4676543565");
+
+ contactDetailsList.add(contactDetails1);
+ contactDetailsList.add(contactDetails2);
+
+ customer.setContactDetailsList(contactDetailsList);
+ return customer;
+ }
+
+}
diff --git a/xstream-introduction/src/main/resources/log4j.properties b/xstream-introduction/src/main/resources/log4j.properties
new file mode 100644
index 0000000000..9cdafc6bdb
--- /dev/null
+++ b/xstream-introduction/src/main/resources/log4j.properties
@@ -0,0 +1,16 @@
+# Root logger option
+log4j.rootLogger=DEBUG, file
+
+# Redirect log messages to console
+# log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+# log4j.appender.stdout.Target=System.out
+# log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+# log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
+
+# Redirect log messages to a log file, support file rolling.
+log4j.appender.file=org.apache.log4j.RollingFileAppender
+log4j.appender.file.File=D:\\Test\\xstream-application.log
+log4j.appender.file.MaxFileSize=5MB
+log4j.appender.file.MaxBackupIndex=10
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
\ No newline at end of file
diff --git a/xstream-introduction/src/test/java/org/baeldung/utility/XStreamSimpleXmlTest.java b/xstream-introduction/src/test/java/org/baeldung/utility/XStreamSimpleXmlTest.java
new file mode 100644
index 0000000000..489960d6ca
--- /dev/null
+++ b/xstream-introduction/src/test/java/org/baeldung/utility/XStreamSimpleXmlTest.java
@@ -0,0 +1,46 @@
+package org.baeldung.utility;
+
+import org.baeldung.initializer.SimpleXstreamInitializer;
+import org.baeldung.pojo.AddressDetails;
+import org.baeldung.pojo.ContactDetails;
+import org.baeldung.pojo.Customer;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.thoughtworks.xstream.XStream;
+
+public class XStreamSimpleXmlTest {
+
+ private Customer customer = null;
+ private String dataXml = null;
+ private XStream xtream = null;
+
+ @Before
+ public void dataSetup() {
+ customer = SimpleDataGeneration.generateData();
+ xtream = SimpleXstreamInitializer.getXstreamInstance();
+ xtream.processAnnotations(Customer.class);
+ xtream.processAnnotations(AddressDetails.class);
+ xtream.processAnnotations(ContactDetails.class);
+ xtream.omitField(Customer.class , "firstName");
+ xtream.registerConverter(new MyDateConverter());
+ //xtream.registerConverter(new MySingleValueConverter());
+ xtream.aliasField("fn", Customer.class, "firstName");
+
+ dataXml = xtream.toXML(customer);
+ System.out.println(dataXml);
+ }
+
+ @Test
+ public void convertDataToXml() {
+ Assert.assertNotNull(dataXml);
+ }
+
+ @Test
+ public void convertXmlToObject() {
+ customer = (Customer) xtream.fromXML(dataXml);
+ Assert.assertNotNull(customer);
+ }
+
+}