commit aa72c687c1a28b656b6f512f243ea653c5cdbe4b Author: DemoUser Date: Thu Oct 6 21:31:30 2016 +0530 Initial Commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..fefd2a5 --- /dev/null +++ b/README.md @@ -0,0 +1,68 @@ +Addressbook Tutorial +==================== + +This tutorial teaches you some of the basic concepts in [Vaadin Framework](https://vaadin.com). It is meant to be +a fast read for learning how to get started - not an example on how application should be +designed. Please note this example uses and requires Java 8 to work. + +![Addressbook Screenshot](addressbook_screenshot.png "Addressbook Screenshot") + + +Running the example from the command line +------------------- +``` +$ mvn jetty:run +``` + +Open [http://localhost:8080/](http://localhost:8080/) + + +Importing in IntelliJ IDEA 14 +-------------------- +These instructions were tested on IntelliJ IDEA 14 CE. You can get it from https://www.jetbrains.com/idea/ + +To get the project up and running in IDEA, do: +- File -> New -> Project from Version Control -> Git +- The URL to use is https://github.com/vaadin/addressbook.git +- If you get a message about "Non-managed pom.xml file found". Choose "Add as Maven Project" +- If you get a message about no JDK or SDK being selected. Choose "Configure" and select your installed JDK. You can also set the JDK using File -> Project Structure +- To start the project, find the "Maven Projects" tab on the right hand side of the screen and navigate to + - Vaadin Web Application -> Plugins -> jetty -> jetty:run + - Click the play button or right click and select Run (Select Debug instead to run in debug mode) + +You should now have a Jetty server running on localhost:8080. Navigate to http://localhost:8080 to play with the application + +Importing in NetBeans 8 +-------------------- +These instructions were tested on NetBeans 8.0.2. You can get it from https://www.netbeans.org + +To checkout and run the project in NetBeans, do: +- Team -> Git -> Clone +- Set repository URL to https://github.com/vaadin/addressbook.git +- Finish +- Right click the imported project (Vaadin Addressbook Application) and select Run +- Select GlassFish Server 4.1 -> Remember in Current IDE Session -> OK + +You should now have a GlassFish server running on localhost:8080 and a browser tab should also be automatically opened with this location + +Importing in Eclipse +-------------------- +These instructions were tested on Eclipse IDE for Java EE Developers Luna SR2. You can get it from http://eclipse.org/downloads/ + +To checkout and run the project in Eclipse, do: +- File -> Import... +- Check out Maven Projects from SCM +- Choose Git from SCM menu + - If you do not see "Git" in the SCM menu, click "Find more SCM connectors in the m2e Marketplace" and install "m2e-egit". Restart Eclipse and start over. +- Set the repository URL to https://github.com/vaadin/addressbook.git +- Right click the imported "addressbook" and choose Run As -> Maven Build... + - Set the goal to "jetty:run" and click "Run" + +You should now have a Jetty server running on localhost:8080. Navigate to [http://localhost:8080/](http://localhost:8080/) to play with the application + +To use the built in server adapters of Eclipse, instead of doing "Run As -> Maven Build..." you can do +- Run As -> Run on Server +- Select the server you want to run on, e.g. Apache Tomcat 8 and click ok +- *Do not use the suggested J2EE Preview server* as it is outdated, deprecated and does not support Servlet 3, which is required for this application + +*** End of documentation \ No newline at end of file diff --git a/addressbook_screenshot.png b/addressbook_screenshot.png new file mode 100644 index 0000000..9501332 Binary files /dev/null and b/addressbook_screenshot.png differ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..34246ca --- /dev/null +++ b/pom.xml @@ -0,0 +1,210 @@ + + + 4.0.0 + com.edurekademo.tutorial + addressbook + war + 2.0 + Vaadin Addressbook example + + + UTF-8 + false + 8.0.0.alpha2 + ${vaadin.version} + + + + + vaadin-prereleases + Vaadin Pre-releases + https://maven.vaadin.com/vaadin-prereleases + + + + vaadin-addons + http://maven.vaadin.com/vaadin-addons + + + + vaadin-snapshots + http://oss.sonatype.org/content/repositories/vaadin-snapshots/ + + false + + + true + + + + + + + vaadin-snapshots + http://oss.sonatype.org/content/repositories/vaadin-snapshots/ + + false + + + true + + + + + + + + com.vaadin + vaadin-compatibility-server + ${vaadin.version} + + + com.vaadin + vaadin-compatibility-shared + ${vaadin.version} + + + com.vaadin + vaadin-compatibility-client-compiled + ${vaadin.version} + + + com.vaadin + vaadin-themes + ${vaadin.version} + + + javax.servlet + javax.servlet-api + 3.0.1 + compile + + + + commons-beanutils + commons-beanutils + 1.9.2 + jar + + + + + log4j + log4j + 1.2.9 + + + org.slf4j + slf4j-api + 1.7.7 + + + org.slf4j + slf4j-simple + 1.7.7 + + + org.slf4j + slf4j-log4j12 + 1.7.7 + + + + + junit + junit + 4.12 + test + + + + + + commons-httpclient + commons-httpclient + 3.1 + + + + org.apache.commons + commons-lang3 + 3.1 + + + + + org.json + json + 20140107 + + + org.codehaus.jackson + jackson-jaxrs + 1.9.4 + + + + + com.sun.xml.security + xml-security-impl + 1.0 + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.2 + + 1.8 + 1.8 + + + + org.eclipse.jetty + jetty-maven-plugin + 9.2.3.v20140905 + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.19.1 + + methods + 10 + + **/Test*.java + **/Test.java + **/TestCase.java + + + **/*Abstract*Test.java + + + + + + addressbook + + + + + + + org.apache.maven.plugins + maven-surefire-report-plugin + 2.19.1 + + + + + diff --git a/src/main/java/com/edurekademo/helper/GenericResourceBundle.java b/src/main/java/com/edurekademo/helper/GenericResourceBundle.java new file mode 100644 index 0000000..c75801b --- /dev/null +++ b/src/main/java/com/edurekademo/helper/GenericResourceBundle.java @@ -0,0 +1,23 @@ +package com.edurekademo.helper; + +import java.util.Enumeration; +import java.util.ResourceBundle; + +public class GenericResourceBundle { + public static String getProperties(String source){ + ResourceBundle rb = ResourceBundle.getBundle("ResourceBundle"); + Enumeration keys = rb.getKeys(); + String value=""; + while (keys.hasMoreElements()) { + + String key = keys.nextElement(); + + if(key.equalsIgnoreCase(source)){ + value = rb.getString(key); + } + } + return value; + } + +} + diff --git a/src/main/java/com/edurekademo/tutorial/addressbook/AddressbookUI.java b/src/main/java/com/edurekademo/tutorial/addressbook/AddressbookUI.java new file mode 100644 index 0000000..5f2c878 --- /dev/null +++ b/src/main/java/com/edurekademo/tutorial/addressbook/AddressbookUI.java @@ -0,0 +1,149 @@ +package com.edurekademo.tutorial.addressbook; + +import javax.servlet.annotation.WebServlet; + +import com.vaadin.annotations.Theme; +import com.vaadin.annotations.Title; +import com.vaadin.annotations.VaadinServletConfiguration; +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinRequest; +import com.vaadin.server.VaadinServlet; +import com.edurekademo.tutorial.addressbook.backend.Contact; +import com.edurekademo.tutorial.addressbook.backend.ContactService; +import com.vaadin.ui.Button; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.v7.data.util.BeanItemContainer; +import com.vaadin.v7.ui.Grid; +import com.vaadin.v7.ui.TextField; + +/* User Interface written in Java. + * + * Define the user interface shown on the Vaadin generated web page by extending the UI class. + * By default, a new UI instance is automatically created when the page is loaded. To reuse + * the same instance, add @PreserveOnRefresh. + */ +@Title("Addressbook") +@Theme("valo") +@Widgetset("com.vaadin.v7.Vaadin7WidgetSet") +public class AddressbookUI extends UI { + + /* + * Hundreds of widgets. Vaadin's user interface components are just Java + * objects that encapsulate and handle cross-browser support and + * client-server communication. The default Vaadin components are in the + * com.vaadin.ui package and there are over 500 more in + * vaadin.com/directory. + */ + TextField filter = new TextField(); + Grid contactList = new Grid(); + Button newContact = new Button("New contact"); + + // ContactForm is an example of a custom component class + ContactForm contactForm = new ContactForm(); + + // ContactService is a in-memory mock DAO that mimics + // a real-world datasource. Typically implemented for + // example as EJB or Spring Data based service. + ContactService service = ContactService.createDemoService(); + + /* + * The "Main method". + * + * This is the entry point method executed to initialize and configure the + * visible user interface. Executed on every browser reload because a new + * instance is created for each web page loaded. + */ + @Override + protected void init(VaadinRequest request) { + configureComponents(); + buildLayout(); + } + + private void configureComponents() { + /* + * Synchronous event handling. + * + * Receive user interaction events on the server-side. This allows you + * to synchronously handle those events. Vaadin automatically sends only + * the needed changes to the web page without loading a new page. + */ + newContact.addClickListener(e -> contactForm.edit(new Contact())); + + filter.setInputPrompt("Filter contacts..."); + filter.addTextChangeListener(e -> refreshContacts(e.getText())); + + contactList + .setContainerDataSource(new BeanItemContainer<>(Contact.class)); + contactList.setColumnOrder("firstName", "lastName", "email"); + contactList.removeColumn("id"); + contactList.removeColumn("birthDate"); + contactList.removeColumn("phone"); + contactList.setSelectionMode(Grid.SelectionMode.SINGLE); + contactList.addSelectionListener( + e -> contactForm.edit((Contact) contactList.getSelectedRow())); + refreshContacts(); + } + + /* + * Robust layouts. + * + * Layouts are components that contain other components. HorizontalLayout + * contains TextField and Button. It is wrapped with a Grid into + * VerticalLayout for the left side of the screen. Allow user to resize the + * components with a SplitPanel. + * + * In addition to programmatically building layout in Java, you may also + * choose to setup layout declaratively with Vaadin Designer, CSS and HTML. + */ + private void buildLayout() { + HorizontalLayout actions = new HorizontalLayout(filter, newContact); + actions.setWidth("100%"); + filter.setWidth("100%"); + actions.setExpandRatio(filter, 1); + + VerticalLayout left = new VerticalLayout(actions, contactList); + left.setSizeFull(); + contactList.setSizeFull(); + left.setExpandRatio(contactList, 1); + + HorizontalLayout mainLayout = new HorizontalLayout(left, contactForm); + mainLayout.setSizeFull(); + mainLayout.setExpandRatio(left, 1); + + // Split and allow resizing + setContent(mainLayout); + } + + /* + * Choose the design patterns you like. + * + * It is good practice to have separate data access methods that handle the + * back-end access and/or the user interface updates. You can further split + * your code into classes to easier maintenance. With Vaadin you can follow + * MVC, MVP or any other design pattern you choose. + */ + void refreshContacts() { + refreshContacts(filter.getValue()); + } + + private void refreshContacts(String stringFilter) { + contactList.setContainerDataSource(new BeanItemContainer<>( + Contact.class, service.findAll(stringFilter))); + contactForm.setVisible(false); + } + + /* + * Deployed as a Servlet or Portlet. + * + * You can specify additional servlet parameters like the URI and UI class + * name and turn on production mode when you have finished developing the + * application. + */ + @WebServlet(urlPatterns = "/*") + @VaadinServletConfiguration(ui = AddressbookUI.class, productionMode = false) + public static class MyUIServlet extends VaadinServlet { + } + +} diff --git a/src/main/java/com/edurekademo/tutorial/addressbook/ContactForm.java b/src/main/java/com/edurekademo/tutorial/addressbook/ContactForm.java new file mode 100644 index 0000000..6a4d0ac --- /dev/null +++ b/src/main/java/com/edurekademo/tutorial/addressbook/ContactForm.java @@ -0,0 +1,116 @@ +package com.edurekademo.tutorial.addressbook; + +import com.vaadin.event.ShortcutAction; +import com.edurekademo.tutorial.addressbook.backend.Contact; +import com.vaadin.ui.Button; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Notification; +import com.vaadin.ui.Notification.Type; +import com.vaadin.ui.themes.ValoTheme; +import com.vaadin.v7.data.fieldgroup.BeanFieldGroup; +import com.vaadin.v7.data.fieldgroup.FieldGroup; +import com.vaadin.v7.ui.DateField; +import com.vaadin.v7.ui.TextField; + +/* Create custom UI Components. + * + * Create your own Vaadin components by inheritance and composition. + * This is a form component inherited from VerticalLayout. Use + * Use BeanFieldGroup to bind data fields from DTO to UI fields. + * Similarly named field by naming convention or customized + * with @PropertyId annotation. + */ +public class ContactForm extends FormLayout { + + Button save = new Button("Save", this::save); + Button cancel = new Button("Cancel", this::cancel); + TextField firstName = new TextField("First name"); + TextField lastName = new TextField("Last name"); + TextField phone = new TextField("Phone"); + TextField email = new TextField("Email"); + DateField birthDate = new DateField("Birth date"); + + Contact contact; + + // Easily bind forms to beans and manage validation and buffering + BeanFieldGroup formFieldBindings; + + public ContactForm() { + configureComponents(); + buildLayout(); + } + + private void configureComponents() { + /* + * Highlight primary actions. + * + * With Vaadin built-in styles you can highlight the primary save button + * and give it a keyboard shortcut for a better UX. + */ + save.setStyleName(ValoTheme.BUTTON_PRIMARY); + save.setClickShortcut(ShortcutAction.KeyCode.ENTER); + setVisible(false); + } + + private void buildLayout() { + setSizeUndefined(); + setMargin(true); + + HorizontalLayout actions = new HorizontalLayout(save, cancel); + actions.setSpacing(true); + + addComponents(actions, firstName, lastName, phone, email, birthDate); + } + + /* + * Use any JVM language. + * + * Vaadin supports all languages supported by Java Virtual Machine 1.6+. + * This allows you to program user interface in Java 8, Scala, Groovy or any + * other language you choose. The new languages give you very powerful tools + * for organizing your code as you choose. For example, you can implement + * the listener methods in your compositions or in separate controller + * classes and receive to various Vaadin component events, like button + * clicks. Or keep it simple and compact with Lambda expressions. + */ + public void save(Button.ClickEvent event) { + try { + // Commit the fields from UI to DAO + formFieldBindings.commit(); + + // Save DAO to backend with direct synchronous service API + getUI().service.save(contact); + + String msg = String.format("Saved '%s %s'.", contact.getFirstName(), + contact.getLastName()); + Notification.show(msg, Type.TRAY_NOTIFICATION); + getUI().refreshContacts(); + } catch (FieldGroup.CommitException e) { + // Validation exceptions could be shown here + } + } + + public void cancel(Button.ClickEvent event) { + // Place to call business logic. + Notification.show("Cancelled", Type.TRAY_NOTIFICATION); + getUI().contactList.select(null); + } + + void edit(Contact contact) { + this.contact = contact; + if (contact != null) { + // Bind the properties of the contact POJO to fiels in this form + formFieldBindings = BeanFieldGroup.bindFieldsBuffered(contact, + this); + firstName.focus(); + } + setVisible(contact != null); + } + + @Override + public AddressbookUI getUI() { + return (AddressbookUI) super.getUI(); + } + +} diff --git a/src/main/java/com/edurekademo/tutorial/addressbook/backend/Contact.java b/src/main/java/com/edurekademo/tutorial/addressbook/backend/Contact.java new file mode 100644 index 0000000..79adab9 --- /dev/null +++ b/src/main/java/com/edurekademo/tutorial/addressbook/backend/Contact.java @@ -0,0 +1,90 @@ +package com.edurekademo.tutorial.addressbook.backend; + +import org.apache.commons.beanutils.BeanUtils; + +import java.io.Serializable; +import java.util.Date; + +/** + * A simple DTO for the address book example. + * + * Serializable and cloneable Java Object that are typically persisted + * in the database and can also be easily converted to different formats like JSON. + */ +// Backend DTO class. This is just a typical Java backend implementation +// class and nothing Vaadin specific. +public class Contact implements Serializable, Cloneable { + + private Long id; + + private String firstName = ""; + private String lastName = ""; + private String phone = ""; + private String email = ""; + private Date birthDate; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + 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 String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public Date getBirthDate() { + return birthDate; + } + + public void setBirthDate(Date birthDate) { + this.birthDate = birthDate; + } + + @Override + public Contact clone() throws CloneNotSupportedException { + try { + return (Contact) BeanUtils.cloneBean(this); + } catch (Exception ex) { + throw new CloneNotSupportedException(); + } + } + + @Override + public String toString() { + return "Contact{" + "id=" + id + ", firstName=" + firstName + + ", lastName=" + lastName + ", phone=" + phone + ", email=" + + email + ", birthDate=" + birthDate + '}'; + } + +} diff --git a/src/main/java/com/edurekademo/tutorial/addressbook/backend/ContactService.java b/src/main/java/com/edurekademo/tutorial/addressbook/backend/ContactService.java new file mode 100644 index 0000000..34da9ec --- /dev/null +++ b/src/main/java/com/edurekademo/tutorial/addressbook/backend/ContactService.java @@ -0,0 +1,103 @@ +package com.edurekademo.tutorial.addressbook.backend; + +import org.apache.commons.beanutils.BeanUtils; + +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** Separate Java service class. + * Backend implementation for the address book application, with "detached entities" + * simulating real world DAO. Typically these something that the Java EE + * or Spring backend services provide. + */ +// Backend service class. This is just a typical Java backend implementation +// class and nothing Vaadin specific. +public class ContactService { + + // Create dummy data by randomly combining first and last names + static String[] fnames = { "Peter", "Alice", "John", "Mike", "Olivia", + "Nina", "Alex", "Rita", "Dan", "Umberto", "Henrik", "Rene", "Lisa", + "Linda", "Timothy", "Daniel", "Brian", "George", "Scott", + "Jennifer" }; + static String[] lnames = { "Smith", "Johnson", "Williams", "Jones", + "Brown", "Davis", "Miller", "Wilson", "Moore", "Taylor", + "Anderson", "Thomas", "Jackson", "White", "Harris", "Martin", + "Thompson", "Young", "King", "Robinson" }; + + private static ContactService instance; + + public static ContactService createDemoService() { + if (instance == null) { + + final ContactService contactService = new ContactService(); + + Random r = new Random(0); + Calendar cal = Calendar.getInstance(); + for (int i = 0; i < 100; i++) { + Contact contact = new Contact(); + contact.setFirstName(fnames[r.nextInt(fnames.length)]); + contact.setLastName(lnames[r.nextInt(fnames.length)]); + contact.setEmail(contact.getFirstName().toLowerCase() + "@" + + contact.getLastName().toLowerCase() + ".com"); + contact.setPhone("+ 358 555 " + (100 + r.nextInt(900))); + cal.set(1930 + r.nextInt(70), + r.nextInt(11), r.nextInt(28)); + contact.setBirthDate(cal.getTime()); + contactService.save(contact); + } + instance = contactService; + } + + return instance; + } + + private HashMap contacts = new HashMap<>(); + private long nextId = 0; + + public synchronized List findAll(String stringFilter) { + ArrayList arrayList = new ArrayList(); + for (Contact contact : contacts.values()) { + try { + boolean passesFilter = (stringFilter == null || stringFilter.isEmpty()) + || contact.toString().toLowerCase() + .contains(stringFilter.toLowerCase()); + if (passesFilter) { + arrayList.add(contact.clone()); + } + } catch (CloneNotSupportedException ex) { + Logger.getLogger(ContactService.class.getName()).log( + Level.SEVERE, null, ex); + } + } + Collections.sort(arrayList, new Comparator() { + + @Override + public int compare(Contact o1, Contact o2) { + return (int) (o2.getId() - o1.getId()); + } + }); + return arrayList; + } + + public synchronized long count() { + return contacts.size(); + } + + public synchronized void delete(Contact value) { + contacts.remove(value.getId()); + } + + public synchronized void save(Contact entry) { + if (entry.getId() == null) { + entry.setId(nextId++); + } + try { + entry = (Contact) BeanUtils.cloneBean(entry); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + contacts.put(entry.getId(), entry); + } + +} diff --git a/src/main/java/com/edurekademo/utilities/CaseInsensitiveComparator.java b/src/main/java/com/edurekademo/utilities/CaseInsensitiveComparator.java new file mode 100644 index 0000000..cee7d85 --- /dev/null +++ b/src/main/java/com/edurekademo/utilities/CaseInsensitiveComparator.java @@ -0,0 +1,99 @@ +package com.edurekademo.utilities; + +import java.lang.reflect.InvocationTargetException; +import java.util.Date; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CaseInsensitiveComparator extends GenericComparator { + + private static final long serialVersionUID = -6836701171640412573L; + private static final Logger LOG =LoggerFactory.getLogger(CaseInsensitiveComparator.class); + + /* + * This function call base GenericComparator(boolean sortAscending) class and set whether sorting is in ascending or descending + * sortAscending = true then ascending + * sortAscending = false then descending + */ + public CaseInsensitiveComparator(boolean sortAscending) { + super(sortAscending); + this.targetMethod = null; + this.sortAscending = sortAscending; + } + /* + * This function call base GenericComparator(boolean sortField) class and set which field we need to sort and sort as asc + */ + public CaseInsensitiveComparator(String sortField) { + super(sortField); + this.targetMethod = prepareTargetMethod(sortField); + this.sortAscending = true; + } + /* + * This function call base GenericComparator(boolean sortField,sortAscending) class and set which field we need to sort and sort based on the boolen value given + * sortAscending = true then ascending + * sortAscending = false then descending + */ + public CaseInsensitiveComparator(String sortField, boolean sortAscending) { + super(sortField, sortAscending); + this.targetMethod = prepareTargetMethod(sortField); + this.sortAscending = sortAscending; + } + + /* + * (non-Javadoc) + * @see com.edurekademo.utilities.GenericComparator#compare(java.lang.Object, java.lang.Object) + */ + public int compare(Object o1, Object o2) { + int response = LESSER; + Object v1,v2; + String returnType; + try { + if(this.targetMethod==null){ + v1=o1; + v2=02; + returnType=o1.getClass().getName(); + }else{ + v1=getValue(o1); + v2=getValue(o2); + returnType=getMethod(o1).getReturnType().getName(); + } + + CompareMode cm = findCompareMode(v1, v2); + if (!cm.equals(CompareMode.DEFAULT)) { + return compareAlternate(cm); + } + response = compareActual(v1, v2, returnType); + } + catch (NoSuchMethodException e){LOG.error(new LoggerStackTraceUtil().getErrorMessage(e));} + catch (IllegalAccessException e){LOG.error(new LoggerStackTraceUtil().getErrorMessage(e));} + catch (InvocationTargetException e){LOG.error(new LoggerStackTraceUtil().getErrorMessage(e));} + return response; + } + /* + * This Method is the overridden compareActual of GenericComparator. + * If the data type is String then it convert string to upper case and compare it with other. + */ + protected int compareActual(Object v1, Object v2, String returnType) { + String obj = returnType; + if ("java.lang.Object".equals(obj) && v1!=null) { + obj = v1.getClass().getName(); + } + int acutal = LESSER; + if (obj.equals(DATATYPE_INTEGER)) { + acutal = ((Integer) v1).compareTo((Integer) v2) * determinePosition(); + } else if (obj.equals(DATATYPE_LONG)) { + acutal = ((Long) v1).compareTo((Long) v2) * determinePosition(); + } else if (obj.equals(DATATYPE_STRING)) { + acutal = ((String) v1).toUpperCase().compareTo(((String) v2).toUpperCase()) * determinePosition(); + } else if (obj.equals(DATATYPE_DATE)) { + acutal = ((Date) v1).compareTo((Date) v2) * determinePosition(); + } else if (obj.equals(DATATYPE_FLOAT)) { + acutal = ((Float) v1).compareTo((Float) v2) * determinePosition(); + } else if (obj.equals(DATATYPE_DOUBLE)) { + acutal = ((Double) v1).compareTo((Double) v2) * determinePosition(); + } + return acutal; + } + +} diff --git a/src/main/java/com/edurekademo/utilities/GenericComparator.java b/src/main/java/com/edurekademo/utilities/GenericComparator.java new file mode 100644 index 0000000..3309221 --- /dev/null +++ b/src/main/java/com/edurekademo/utilities/GenericComparator.java @@ -0,0 +1,277 @@ +package com.edurekademo.utilities; +import java.io.Serializable; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Comparator; +import java.util.Date; + +/** +* Sorting - Generic Comparator +* +* @author Seshagiri Sriram +* @version 1.0 +* @since Janauary 12, 2015 +* +* This is an adaptation of a genenic comparator found on github linked from myjeeva.com +* Many thanks for the code! +*/ + +@SuppressWarnings("rawtypes") +public class GenericComparator implements Comparator, Serializable { + protected static final long serialVersionUID = -2293914106471884607L; + protected static final int LESSER = -1; + protected static final int EQUAL = 0; + protected static final int GREATER = 1; + protected static final String METHOD_GET_PREFIX = "get"; + protected static final String DATATYPE_STRING = "java.lang.String"; + protected static final String DATATYPE_DATE = "java.util.Date"; + protected static final String DATATYPE_INTEGER = "java.lang.Integer"; + protected static final String DATATYPE_LONG = "java.lang.Long"; + protected static final String DATATYPE_FLOAT = "java.lang.Float"; + protected static final String DATATYPE_DOUBLE = "java.lang.Double"; + protected static final String DATATYPE_BOOLEAN = "java.lang.Boolean"; + + protected enum CompareMode { EQUAL, LESS_THAN, GREATER_THAN, DEFAULT } + // generic comparator attributes + protected String targetMethod; + protected boolean sortAscending; + + /** + *

default constructor - assumes comparator for Type List

+ * + *

For Example-

+ * List<Integer> aa = new ArrayList<Integer>();
+ * List<String> bb = new ArrayList<String>();
+ * List<Date> cc = new ArrayList<Date>();
+ *

and so on..

+ * + * @param sortAscending - a {@link boolean} - true ascending order or false descending order + */ + + public GenericComparator(boolean sortAscending) { + super(); + this.targetMethod = null; + this.sortAscending = sortAscending; + } + + /** + *

constructor with sortField parameter for Derived type of Class default sorting is ascending order

+ * + *

For Example-

+ *

PersonVO person = new PersonVO();
+ * person.setId(10001);
+ * person.setName("Jacob");
+ * person.setHeight(5.2F);
+ * person.setEmailId("jacob@example.example");
+ * person.setSalary(10500L);
+ * person.setDob(new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH).parse("Jan 1, 1970"));

+ *

and person2, person3, so on.. And Defining & adding all the created objects in to below list

+ *

List<PersonVO> persons = new ArrayList<PersonVO>();
+ * persons.add(person1);
+ * persons.add(person2);
+ * persons.add(person3);
and so on
+ * + * @param sortField - a {@link java.lang.String} - which field requires sorting; as per above example "sorting required for name field" + */ + public GenericComparator(String sortField) { + super(); + this.targetMethod = prepareTargetMethod(sortField); + this.sortAscending = true; + } + + /** + *

constructor with sortField, sortAscending parameter for Derived type of Class

+ * + *

For Example-

+ *

PersonVO person = new PersonVO();
+ * person.setId(10001);
+ * person.setName("Jacob");
+ * person.setHeight(5.2F);
+ * person.setEmailId("jacob@example.example");
+ * person.setSalary(10500L);
+ * person.setDob(new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH).parse("Jan 1, 1970"));

+ *

and person2, person3, so on.. And Defining & adding all the created objects in to below list

+ *

List<PersonVO> persons = new ArrayList<PersonVO>();
+ * persons.add(person1);
+ * persons.add(person2);
+ * persons.add(person3);
and so on
+ * @param sortField - a {@link java.lang.String} - which field requires sorting; as per above example "sorting required for name field" + * @param sortAscending - a {@link boolean} - true ascending order or false descending order + */ + + public GenericComparator(String sortField, boolean sortAscending) { + super(); + this.targetMethod = prepareTargetMethod(sortField); + this.sortAscending = sortAscending; + } + + /** + * {@inheritDoc} + */ + public int compare(Object o1, Object o2) { + int response = LESSER; + Object v1,v2; + String returnType; + try { + if(this.targetMethod==null){ + v1=o1; + v2=02; + returnType=o1.getClass().getName(); + }else{ + v1=getValue(o1); + v2=getValue(o2); + returnType=getMethod(o1).getReturnType().getName(); + } + + CompareMode cm = findCompareMode(v1, v2); + if (!cm.equals(CompareMode.DEFAULT)) { + return compareAlternate(cm); + } + response = compareActual(v1, v2, returnType); + } + // in JSE 1.7 the below is accepted + /* + catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException nsme) { + } */ + catch (NoSuchMethodException e){ + LoggerStackTraceUtil.printErrorMessage(e); + }catch (IllegalAccessException e){ + LoggerStackTraceUtil.printErrorMessage(e); + }catch (InvocationTargetException e){ + LoggerStackTraceUtil.printErrorMessage(e); + } + return response; + } + +//---------------------------------------------------------------------------------// +// Private methods used by {@link com.myjeeva.comparator.GenericComparator} // +//---------------------------------------------------------------------------------// + /** + * alternate to actual value comparison i.e., either (lsh & rhs) one the value could be null + * + * @param cm - a enum used to idetify the position for sorting + */ + protected int compareAlternate(CompareMode cm) { + int compareState = LESSER; + switch(cm) { + case LESS_THAN: + compareState = LESSER * determinePosition(); + break; + case GREATER_THAN: + compareState = GREATER * determinePosition(); + break; + case EQUAL: + compareState = EQUAL * determinePosition(); + break; + } + return compareState; +} + /** + * actual value comparison for sorting; both lsh & rhs value available + * + * @param v1 - value of lhs + * @param v2 - value of rhs + * @param returnType - datatype of given values + * @return int - compare return value + */ + private int compareActual(Object v1, Object v2, String returnType) { + String obj = returnType; + if ("java.lang.Object".equals(obj) && v1!=null) { + obj = v1.getClass().getName(); + } + int acutal = LESSER; + + if (obj.equals(DATATYPE_INTEGER)) { + acutal = ((Integer) v1).compareTo((Integer) v2) * determinePosition(); + } else if (obj.equals(DATATYPE_LONG)) { + acutal = ((Long) v1).compareTo((Long) v2) * determinePosition(); + } else if (obj.equals(DATATYPE_STRING)) { + acutal = ((String) v1).compareTo((String) v2) * determinePosition(); + } else if (obj.equals(DATATYPE_DATE)) { + acutal = ((Date) v1).compareTo((Date) v2) * determinePosition(); + } else if (obj.equals(DATATYPE_FLOAT)) { + acutal = ((Float) v1).compareTo((Float) v2) * determinePosition(); + } else if (obj.equals(DATATYPE_DOUBLE)) { + acutal = ((Double) v1).compareTo((Double) v2) * determinePosition(); + } else if (obj.equals(DATATYPE_BOOLEAN)) { + acutal = ((Boolean) v1).compareTo((Boolean) v2) * determinePosition(); + } + return acutal; + } + /** + * preparing target name of getter method for given sort field + * + * @param name a {@link java.lang.String} + * @return methodName a {@link java.lang.String} + */ + protected final static String prepareTargetMethod(String name) { + StringBuffer fieldName = new StringBuffer(METHOD_GET_PREFIX); + fieldName.append(name.substring(0, 1).toUpperCase()).append(name.substring(1)); + return fieldName.toString(); + } + + /** + * fetching method from Class object through reflect + * + * @param obj - a {@link java.lang.Object} - input object + * @return method - a {@link java.lang.reflect.Method} + * @throws NoSuchMethodException + */ + protected final Method getMethod(Object obj) throws NoSuchMethodException { + return obj.getClass().getMethod(targetMethod, null); + } + + /** + * dynamically invoking given method with given object through reflect + * + * @param method - a {@link java.lang.reflect.Method} + * @param obj - a {@link java.lang.Object} + * @return object - a {@link java.lang.Object} - return of given method + * @throws InvocationTargetException + * @throws IllegalAccessException + */ + + private final static Object invoke(Method method, Object obj) throws InvocationTargetException, IllegalAccessException { + return method.invoke(obj, null); + } + /** + * fetching a value from given object + * + * @param obj - a {@link java.lang.Object} + * @return object - a {@link java.lang.Object} - return of given method + * @throws InvocationTargetException + * @throws IllegalAccessException + * @throws NoSuchMethodException + */ + protected Object getValue(Object obj) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException { + return invoke(getMethod(obj), obj); + } + /** + * identifying the comparison mode for given value + * + * @param o1 - a {@link java.lang.Object} + * @param o2 - a {@link java.lang.Object} + * @return compareMode - a {@link com.edurekademo.utilities.GenericComparator.CompareMode} + */ + protected CompareMode findCompareMode(Object o1, Object o2) { + CompareMode cm = CompareMode.LESS_THAN; + if(null != o1 & null != o2) { + cm = CompareMode.DEFAULT; + } else if (null == o1 & null != o2) { + cm = CompareMode.LESS_THAN; + } else if (null != o1 & null == o2) { + cm = CompareMode.GREATER_THAN; + } else if (null == o1 & null == o2) { + cm = CompareMode.EQUAL; + } + return cm; + } + /** + * Determining positing for sorting + * + * @return -1 to change the sort order if appropriate. + */ + protected int determinePosition() { + return sortAscending ? GREATER : LESSER; + } +} diff --git a/src/main/java/com/edurekademo/utilities/HexAsciiConvertor.java b/src/main/java/com/edurekademo/utilities/HexAsciiConvertor.java new file mode 100644 index 0000000..e3d829d --- /dev/null +++ b/src/main/java/com/edurekademo/utilities/HexAsciiConvertor.java @@ -0,0 +1,59 @@ +package com.edurekademo.utilities; + +public class HexAsciiConvertor { + /** + * Method to convert hexadecimal values into ascii + * method is return the ascii value + * @param hexValue + * @return outputAscii + */ + + public static String convertHexToASCII(String hexValue) + { + StringBuilder outputAscii = new StringBuilder(); + String asciiValue = null; + try{ + if(hexValue!=null){ + for (int i = 0; i < hexValue.length(); i += 2) + { + String str = hexValue.substring(i, i + 2); + outputAscii.append((char) Integer.parseInt(str, 16)); + } + asciiValue = outputAscii.toString(); + } + } + catch(Exception ex){ + LoggerStackTraceUtil.printErrorMessage(ex); + } + return asciiValue; + } + + /** + * Method to convert ascii values into hexadecimal + * method is returning the hexadecimal value + * @param asciiValue + * @return hex + */ + + public static String convertAsciiToHex(String asciiValue) + { + String hexvalue = null; + try { + + if(asciiValue!=null) + { + char[] chars = asciiValue.toCharArray(); + StringBuffer hex = new StringBuffer(); + for (int i = 0; i < chars.length; i++) + { + hex.append(Integer.toHexString((int) chars[i])); + } + hexvalue= hex.toString(); + } + } + catch (Exception e) { + LoggerStackTraceUtil.printErrorMessage(e); + } + return hexvalue; + } +} \ No newline at end of file diff --git a/src/main/java/com/edurekademo/utilities/LoggerStackTraceUtil.java b/src/main/java/com/edurekademo/utilities/LoggerStackTraceUtil.java new file mode 100644 index 0000000..3631b78 --- /dev/null +++ b/src/main/java/com/edurekademo/utilities/LoggerStackTraceUtil.java @@ -0,0 +1,59 @@ +package com.edurekademo.utilities; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +// Class used to log the print stack trace items +public class LoggerStackTraceUtil { + + private static final Logger LOG =LoggerFactory.getLogger(LoggerStackTraceUtil.class); + private int maxCount=3; + + /** + * @param th - The exception that was thrown and to be logged. + * @return at very least the 1st error, if stacktrace is more than 1, then it also + * returns the immediate cause + * + * Note this function cannot be made static for thread safety.. + */ + public String getErrorMessage(Throwable th){ + if (th==null) return ""; + StringBuilder b = new StringBuilder(""); + String [] aryError = ExceptionUtils.getRootCauseStackTrace(th); + b.append(aryError[0].trim()); + if (aryError.length >= 2){ + b.append(String.format("%nCause:%s",aryError[1].trim())); + } + if (aryError.length >= maxCount){ + b.append(String.format("%nCause:%s",aryError[2].trim())); + } + return b.toString(); + } + + // Static Logger function + public static void printErrorMessage(Throwable th) + { + try{ + // log the error caused by + LOG.error("Error Cause: {}",th.getMessage()); + // Conditional statement to check the length of the array + int count=0; + for(StackTraceElement stackTrace:th.getStackTrace()){ + if(count<=25){ + LOG.error("Error Class: {} and Line Number: {}",stackTrace.getClassName(),stackTrace.getLineNumber()); + }else{ + break; + } + count++; + } + } + catch(Exception e) + { + // log the exception error + LoggerStackTraceUtil.printErrorMessage(e); + } + + + } + +} diff --git a/src/main/java/com/edurekademo/utilities/PrepareTargetMethod.java b/src/main/java/com/edurekademo/utilities/PrepareTargetMethod.java new file mode 100644 index 0000000..fe24e77 --- /dev/null +++ b/src/main/java/com/edurekademo/utilities/PrepareTargetMethod.java @@ -0,0 +1,17 @@ +package com.edurekademo.utilities; + +public class PrepareTargetMethod { + + private static final String METHOD_GET_PREFIX = "get"; + /** + * preparing target name of getter method for given sort field + * + * @param name a {@link java.lang.String} + * @return methodName a {@link java.lang.String} + */ + public String prepareTargetMethod(String name) { + StringBuffer fieldName = new StringBuffer(METHOD_GET_PREFIX); + fieldName.append(name.substring(0, 1).toUpperCase()).append(name.substring(1)); + return fieldName.toString(); + } +} diff --git a/src/main/java/com/edurekademo/utilities/PropertyHelper.java b/src/main/java/com/edurekademo/utilities/PropertyHelper.java new file mode 100644 index 0000000..a1bf5ab --- /dev/null +++ b/src/main/java/com/edurekademo/utilities/PropertyHelper.java @@ -0,0 +1,97 @@ +package com.edurekademo.utilities; + +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Properties; +@SuppressWarnings("unchecked") + +/** + * Helper Class to load Properties from a property file to be passed to caller for execution. + * Multiple properties can be loaded. + * Note that if same property is specified multiple times in a single file, there is no guaranteed "Winner" + * Also note in the case of loading multiple files and duplicate definition of properties across files, + * the last loaded property file "wins". + * The getProperty()/get() methods also returns "" silently if no such query exists. + * @author Seshagiri Sriram + * @version 1.0 + * @see PropertyLoader + */ + +public final class PropertyHelper { + +/** + * hMapProperties contains the hashmap of key/value pairs associated with each property + */ +protected final static HashMap HMAPPROPERTIES = new HashMap(); + + +/** + * @param propertyFile + * @return + */ +public static HashMap loadProperties(String propertyFile) { + Properties properties = PropertyLoader.loadProperties(propertyFile); + Enumeration keys = (Enumeration) properties.propertyNames(); + while (keys.hasMoreElements()) { + String tmpKey = (String) keys.nextElement(); + HMAPPROPERTIES.put(tmpKey,properties.getProperty(tmpKey)); + + } + return HMAPPROPERTIES; + } + + +/** + * @param propertyName + * @return + */ +public static String getProperty(String propertyName){ + String propertyValue = ""; + try { + propertyValue = (String) HMAPPROPERTIES.get(propertyName); + } + catch (Exception e){ + LoggerStackTraceUtil.printErrorMessage(e); + propertyValue = ""; + } + finally { + } + return propertyValue; + } + +/** + * Function used to get the default value if the property is null + * @param propertyName - Name of the property + * @param strDefault - Default value that needs to be returned if the value is null + * @return Property value/Default Value as String + */ +public static String getProperty(String propertyName,String strDefault){ + String propertyValue = ""; + try { + propertyValue = (String) HMAPPROPERTIES.get(propertyName); + // Check the property value is null/not + if(propertyValue == null){ + // Assign the default value to the propertyValue + propertyValue=strDefault; + } + } + catch (Exception e){ + LoggerStackTraceUtil.printErrorMessage(e); + propertyValue = ""; + } + finally { + } + return propertyValue; + } + +/** + * A convenience method (aliasing getProperty) + * @param propertyName property to be retrieved. + * @return + * @see getProperty + */ +public static String get(String propertyName){ + return getProperty(propertyName); +} + } + diff --git a/src/main/java/com/edurekademo/utilities/PropertyLoader.java b/src/main/java/com/edurekademo/utilities/PropertyLoader.java new file mode 100644 index 0000000..628918a --- /dev/null +++ b/src/main/java/com/edurekademo/utilities/PropertyLoader.java @@ -0,0 +1,107 @@ +package com.edurekademo.utilities; + +import java.io.InputStream; +import java.util.Enumeration; +import java.util.Locale; +import java.util.Properties; +import java.util.ResourceBundle; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +/** + * Looks up a resource named 'name' in the classpath. The resource must map + * to a file with .properties extention. The name is assumed to be absolute + * and can use either "/" or "." for package segment separation with an + * optional leading "/" and optional ".properties" suffix. Thus, the + * following names refer to the same resource: + * + * @author Seshagiri Sriram + * @version 1.0 + * @param name classpath resource name [may not be null] + * @param loader classloader through which to load the resource [null + * is equivalent to the application loader] + * @return resource converted to java.util.Properties [may be null if the + * resource was not found and THROW_ON_LOAD_FAILURE is false] + * @throws IllegalArgumentException if the resource was not found and + * THROW_ON_LOAD_FAILURE is true + */ + +public class PropertyLoader +{ + + private static final boolean THROW_ON_LOAD_FAILURE = true; + private static final boolean LOAD_AS_RESOURCE_BUNDLE = false; + private static final String SUFFIX = ".properties"; + + /** + * Logger enabled for the current class + */ + private static final Logger LOG =LoggerFactory.getLogger(PropertyLoader.class); + + /** + * A convenience overload of {@link #loadProperties(String, ClassLoader)} + * that uses the current thread's context classloader. + */ + + public static Properties loadProperties (final String name) { + return loadProperties (name, Thread.currentThread ().getContextClassLoader ()); + } + + @SuppressWarnings("rawtypes") + public static Properties loadProperties (String names, ClassLoader loader) + { + String name = null; + ClassLoader loaders; + if (names == null) throw new IllegalArgumentException ("null input: name"); + if (names.startsWith ("/")) name = names.substring (1); + if (names.endsWith (SUFFIX)) name = names.substring (0, names.length () - SUFFIX.length ()); + Properties result = null; + InputStream in = null; + try { + if (loader == null) + loaders = ClassLoader.getSystemClassLoader (); + if (LOAD_AS_RESOURCE_BUNDLE) + { + name = name.replace ('/', '.'); // Throws MissingResourceException on lookup failures: + final ResourceBundle rb = ResourceBundle.getBundle (name, Locale.getDefault (), loaders); + result = new Properties (); + for (Enumeration keys = rb.getKeys (); keys.hasMoreElements ();) + { + final String key = (String) keys.nextElement (); + final String value = rb.getString (key); + result.put (key, value); + } + } + else { + name = name.replace ('.', '/'); + if (! name.endsWith (SUFFIX)) name = name.concat (SUFFIX); // Returns null on lookup failures: + if(loader!=null) + in = loader.getResourceAsStream (name); + if (in != null) { + result = new Properties (); + result.load (in); // Can throw IOException + } + } + } + catch (Exception e) { + result = new Properties (); + LoggerStackTraceUtil.printErrorMessage(e); + } + finally { + if (in != null) + try + { + in.close (); + } + catch (Throwable ignore) {} + } + if (THROW_ON_LOAD_FAILURE && (result == null)) + { + // LOG exception... Do not re-throw this.. as I do not expect users to catch this exception :-) + //throw new IllegalArgumentException ("could not load [" + name + "]"+ " as " + (LOAD_AS_RESOURCE_BUNDLE ? "a resource bundle" : "a classloader resource")); + result = new Properties (); + } + return result; + } + +} \ No newline at end of file diff --git a/src/main/java/com/edurekademo/utilities/StringUtilities.java b/src/main/java/com/edurekademo/utilities/StringUtilities.java new file mode 100644 index 0000000..2f83a35 --- /dev/null +++ b/src/main/java/com/edurekademo/utilities/StringUtilities.java @@ -0,0 +1,194 @@ +package com.edurekademo.utilities; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * An utility class that is used to split an string into an array list and providing mechanism to + * build a HashMap value based on a variable number of arguements. + * @author Seshagiri Sriram + * @version 1.0 + * + */ +public class StringUtilities { + /** + * The string separator for splitting a string into a list + */ + private final static String COMMA_SEPARATOR = ","; + /** + * The String separator for splitting a parameter value. + * Parameters are expected to be in form: "parametername=value" + */ + private final static String PARAM_SEPARATOR = "="; + /** + * The String separator for splitting a parameter value into appropriate type. + * Required for HQL Queries, never for Native SQL queries + * Parameters are expected to be in form: "parametername=value:type (int, string, float, double)" + */ + private final static String TYPE_SEPARATOR = ";"; + /** + * The String separator for splitting a date parameter value into appropriate format. + */ + private final static String DATEFORMAT_SEPARATOR = "@"; + + /** + * The method to be invoked to convert a given String value to a specific Object type + */ + private final static String CONVERTOR_METHOD_NAME = "valueOf" ; + + /** + * The String to represent the type "DATE" + */ + private final static String DATE_TYPE = "date" ; + + /** + * Default Date format to which the date will be formatted + */ + + private final static String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss" ; + /** + * Variable to represent the type "STRING" + */ + private final static String STRING_TYPE ="string"; + /** + * Logger enabled for the current class + */ + private static final Logger LOG =LoggerFactory.getLogger(StringUtilities.class); + + /** Primitive type name -> class map. */ + private static final HashMap> PRIMITIVE_NAME_TYPE_MAP = new HashMap>(); + + /** Setup the primitives map. */ + static { + PRIMITIVE_NAME_TYPE_MAP.put("boolean", Boolean.class); + PRIMITIVE_NAME_TYPE_MAP.put("int", Integer.class); + PRIMITIVE_NAME_TYPE_MAP.put("long", Long.class); + PRIMITIVE_NAME_TYPE_MAP.put("float", Float.class); + PRIMITIVE_NAME_TYPE_MAP.put("double", Double.class); + } + + /** + * given a comma separated string and type, returns an ArrayList of specific types + * @param strParamValueList The string (assumed to be comma separated). Usually meant for use in creating + * parameter values for passing in IN Clauses + * @param type The type of the Arraylist passed + * @return ArrayList if passed value is not null or empty, null otherwise + */ + public static List convertStringToList(String strParamValueList,String type){ + if (strParamValueList==null||strParamValueList.trim().isEmpty()) return null; + ArrayList list = new ArrayList(); + String arr[] = strParamValueList.trim().split(COMMA_SEPARATOR); + for(String tmpString: arr){ + list.add(convert(tmpString,type)); + } + return list; + } + + /** + * given a variable list of String parameters, forms a hash map + * @param strParamValueList Variable list of arguments each of format: key=kevalue;type. + * For the type date,you can even pass the dateformat value as key=keyvalue@dateformat;type. + * If dateformat is not passed default format yyyy-MM-dd HH:mm:ss will be taken. + * @return HashMap if no arguments are passed, returns an empty list, else populated hashmap + * support only int, string, boolean, float, double, long, date + */ + public static HashMap createParameterList(String... strParamValueList){ + HashMap hMap = new HashMap(); + for(String strArg: strParamValueList){ + String type = null; + if(strArg.contains(TYPE_SEPARATOR)){ + type = strArg.split(TYPE_SEPARATOR)[1]; + strArg = strArg.split(TYPE_SEPARATOR)[0]; + } + if (strArg.contains(PARAM_SEPARATOR)){ + String arr[] = strArg.split(PARAM_SEPARATOR); + if (arr[1].contains(COMMA_SEPARATOR)){ + hMap.put(arr[0], convertStringToList(arr[1],type)); + } + else { + hMap.put(arr[0], convert(arr[1],type)); + } + } + } + return hMap; + } + + /** + * Converts the given String value to the intended type of Object + * @param value The String value to be converted + * @param type The type to which the value needs to be converted + * @return Object Returns values as such if type or value is empty or null,else returns the converted Object + */ + private static Object convert(String value, String types) { + + Class finalClass = null ; + //If value or type passed is null or empty or string return back value as such + if ((value == null) || value.isEmpty() || types == null || types.isEmpty() || types.equalsIgnoreCase(STRING_TYPE)) return value; + + String type = types.toLowerCase(); + + if (type.equals(DATE_TYPE)) return convertStringToDate(value); + + //Based on the passed type load the wrapper class. + //If the given type not permitted returns values as such + if(PRIMITIVE_NAME_TYPE_MAP.containsKey(type)) + finalClass = PRIMITIVE_NAME_TYPE_MAP.get(type); + + try { + //Invoking the valueOf method of the Wrapper Class dynamically using reflection + if(finalClass!=null){ + Method method = finalClass.getMethod(CONVERTOR_METHOD_NAME, String.class); + int mods = method.getModifiers(); + if (Modifier.isStatic(mods) && Modifier.isPublic(mods)) { + return method.invoke(null, value); + } + } + } + catch (NoSuchMethodException e) { + LoggerStackTraceUtil.printErrorMessage(e); + } + catch (IllegalAccessException e) { + // this won't happen + LoggerStackTraceUtil.printErrorMessage(e); + } + catch (InvocationTargetException e) { + // when this happens, the string cannot be converted to the intended type + // we are ignoring it here - the original string will be returned + LoggerStackTraceUtil.printErrorMessage(e); + } + + return value; + } + + /** + * Convert the given date value in string to date object + * @param dateString The date to be formatted + * @return Object Returns the corresponding Date object + */ + private static Object convertStringToDate(String dateString) { + String dateFormat = null; + Object finalDate = null; + String dateStringVal=null; + //If the incoming date string contains the format as well parse using the given format, else parse using default + dateFormat = (dateString.contains(DATEFORMAT_SEPARATOR)) ? dateString.split(DATEFORMAT_SEPARATOR)[1] : DATE_FORMAT ; + dateStringVal = (dateString.contains(DATEFORMAT_SEPARATOR)) ? dateString.split(DATEFORMAT_SEPARATOR)[0] : dateString ; + SimpleDateFormat dateFormatter = new SimpleDateFormat(dateFormat); + + try{ + finalDate = dateFormatter.parse(dateStringVal); + }catch(ParseException e){ + LoggerStackTraceUtil.printErrorMessage(e); + } + return finalDate; + } +}