Java – Pro9ramming https://pro9ramming.com Software craftsman's blog Wed, 15 Apr 2020 17:51:12 +0000 en-US hourly 1 https://wordpress.org/?v=6.5.3 Mapping of ResultSet to objects https://pro9ramming.com/mapping-of-resultset-to-objects/ Wed, 12 Apr 2017 13:49:36 +0000 http://pro9ramming.com/blog/?p=461 Continue reading Mapping of ResultSet to objects]]> This tutorial shows how to create a simple mapping of ResultSet data to object, of course by using  Java programming language. This is basically a simple ORM (Object Relational Mapper) which can be customized for different needs. ORM represents a pattern for accessing database  records using object-oriented language. There are different implementations of ORM libraries  (like Hibernate). Using a library, or implementing you own ORM depends on your needs. At least, in this tutorial you can get an insight of how ORM libraries are implemented.

For purposes of this tutorial, JDBC is going to be used. JDBC is the API that enables the client to talk to the database (usually relational). After creating a connection you can execute queries using Statements. PreparedStatement represents a type of Statement which accepts parameters. ResultSet is a class that is used to get the data from query that is executed using a Statement.

Reading class properties, annotations, invoking methods and much more is done using reflection. Everyone knows that metadata is data about data. But what is metalanguage ? It’s easy: Metalanguage is a language that describes another language. Reflection is the ability of language to be it’s own metalanguage. As you might suppose, it’s an abstract way of thinking. Class has properties which can have annotations. Annotations are generally used to give some more info about property, method, class etc.  They can be viewed as metadata.

ResultSet class doesn’t contain only data, it contains also contains metadata. As you can see in the picture, headers of columns (or column names) are basically metadata (that includes column types).

For example, next code reads column names types from ResultSet metadata:

PreparedStatement ps = conn.prepareStatement("select * from car");
            ResultSet rs = ps.executeQuery();
            for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
                String columnName = rs.getMetaData().getColumnName(i);
                String columnType = rs.getMetaData().getColumnTypeName(i);
                System.out.println(columnName+" - "+columnType);
            }

Annotations can be accessed at compile time and at runtime [1]. For example, annotation that should be inspected at runtime should have next annotation:

@Retention(RetentionPolicy.RUNTIME)

Type of annotation is defined by using java.lang.annotation.ElementType enum which has fields: CONSTRUCTOR, FIELD, METHOD, TYPE. ElementType is parameter in @Target annotations. Annotation can be inspected on class, field or method by calling isAnnotationPresent() method.  For purposes of this tutorial, Column annotation is going to be created. It’s going to have name parameter, and should be accesible at runtime.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface Column {
    String name() default "";
}

Java has a class which name is Class. For purposes of this tutorial, Class<? extends Object> parameter is going to be used. It defines a class that extends Object (root class).  Fields of a class are accessed by using getFields() method, but it won’t read private fields, so getDeclaredFields() is used instead. That would retur an array of fields (Field[]). Private field has to be set as accessible by using method setAccessible(true)[2]. By using this techniques, reading class fields (including types) is easy:

public static void printFields(Class<? extends Object> cls){
        for(Field field : cls.getDeclaredFields()){
            field.setAccessible(true);
            System.out.println(field.getName()+" - "+field.getType().getName());
        }
    }

So, we have a result set which returns metadata (column headers) and we have a class which has fields with names (and annotations). Those are 2 different kinds of metadata. We are going to map them together. First of all, field name is also a metadata, so if it’s the same as the corresponding column header, mapping could be achieved without reading the annotation. But fields are usually named by using camelCase, and column headers by using Snake case (or underscore) [3]. So if Column annotation is not present, field’s name should be translated to Snake case:

public class StringUtil {
    public static String getSnakeCase(String str) {
        if (str == null) {
            return null;
        }
        if (str.equals("")) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        int lastIndex = 0;
        //starts from 1 to cover Pascal case too
        for (int i = 1; i <= str.length(); i++) {
            if (i == str.length() || Character.isUpperCase(str.charAt(i))) {
                sb.append(str.substring(lastIndex, i).toLowerCase());
                lastIndex = i;
                if (i < str.length()) 
                    sb.append("_");
            }
        }
        return sb.toString();
    }
}

If Column annotation is present on the field, it’s name parameter is going to be used when mapping. For purposes of this tutorial, Mapper class is created. It has 2 methods: getFieldMap() and map(). getFieldMap() is used internally by map() method. It basically creates a map of fields and corresponding names. Map method returns list of mapped objects from ResultSet records. It goes through records and maps columns to fields. If field is not found, it jumps over it. So only intersection of field names and column headers is mapped.

public class Mapper{
public static Map<String, Field> getFieldMap(Class<? extends Object> cls){
        Map<String, Field> map = new HashMap<>();
        for (Field field : cls.getDeclaredFields()) {
            field.setAccessible(true);
            String name = StringUtil.getSnakeCase(field.getName());
            if (field.isAnnotationPresent(Column.class)) {
                Column c = field.getAnnotation(Column.class);
                name = c.name();
            }
            map.put(name.toLowerCase(), field);
        }
        return map;
    }
    
    public static List<Object> map(Class<? extends Object> cls, ResultSet rs){
        List<Object> list = new ArrayList<>();
        Map<String, Field> fieldMap = Mapper.getFieldMap(cls);
        try{
            while(rs.next()){
                Object obj = cls.newInstance();
                for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
                    String columnName = rs.getMetaData().getColumnName(i).toLowerCase();
                    Field field = fieldMap.get(columnName);
                    if(field != null)
                        field.set(obj, rs.getObject(i));
                }
                list.add(obj);
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        return list;
}
}

Two facts should be emphasized: SQL type and corresponding field type must be compatible, and class should have a default constructor. Because map() method returns list of objects, while iterating through that list, each object should be type-cast-ed to appropriate class. Example:

List<Object> list = Mapper.map(Person.class, resultSet);
            for (Object obj : list){
                Person person = (Person)obj;
                System.out.println(person.toString());
            }

Class used for mapping is Person which has 4 fields: id, firstName, lastName, birthDate. As you can see only birthDate has Column annotation which defines DOB (Date Of Birth) name for query metadata. So ResultSet metadata has next column headers: id, first_name, last_name, dob. FirstName and LastName are converted to Snake case. Person class also has default constructor, getters and setters, and toString() method.

public class Person {
    private Integer id;
    private String firstName;
    private String lastName;
    @Column(name="dob")
    private Date birthDate;

    public Person() {}
    
    public Integer getId() {
        return id;
    }

    public void setId(Integer 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 Date getBirthDate() {
        return birthDate;
    }

    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }
    
    @Override
    public String toString() {
        return "Person{" + "id=" + getId() + ", firstName=" + getFirstName() + ", lastName=" + getLastName() + ", birthDate=" + getBirthDate() + '}';
    }
}

Techniques represented in this tutorial only work for “select” queries (reading data). Other operations like “insert”, “update” and “delete” can also be created in a similar manner, so you can create a generic CRUD using JDBC. That would be a different way to implement a DAO pattern if some of your data mapping logic is redundant.

References:

[1] Jenkov annotations

[2] Accessing private fields

[3] Snake case

]]>
JSF 2.2 Image upload and serve over Image Servlet https://pro9ramming.com/jsf-2-2-image-upload-and-serve-over-image-servlet/ Wed, 12 Apr 2017 13:35:39 +0000 http://pro9ramming.com/blog/?p=459 Continue reading JSF 2.2 Image upload and serve over Image Servlet]]> Purpose of this tutorial is to make image upload (with validation) in JSF 2.2 and serve uploaded images over Image Servlet. JSF 2.2 has support for file upload, and you don’t need third party libraries anymore. We will upload images on to absolute path and serve them over stream inside registered image servlet. This way of serving image files is perfect if you are using Eclipse with some servlet container (like Tomcat) on Windows OS, and you want to place your images on absolute path in your file system.

First create new “Dynamic Web Project” in Eclipse. First we are going to add some utility classes. StreamUtil class has one static method WriteToOutputStream() which writes data from input to output stream using a buffer with a certain size:

package com.pro9ramming;

import java.io.*;

public class StreamUtil {
	public static final int BUFFER_SIZE = 10240;

	public static void WriteToOutputStream(InputStream input, OutputStream output) throws IOException {
		byte[] buffer = new byte[BUFFER_SIZE];
		int numOfBytes = 0;
		while ((numOfBytes = input.read(buffer)) > 0)
			output.write(buffer, 0, numOfBytes);
	}
}

While there are bytes that need to be copied, this it takes them into the buffer and outputs them to OutputStream. This code is going to be used twice, later in the tutorial (for saving and serving images).

Next class is FileUtil which has 4 static methods:

  • Boolean uploadedFileIsImage(String imageLocation) checks if uploaded file is image by using MIME types. It creates MimetypesFileTypeMap and adds MIME types which need to be checked to that object (all images: png tif jpg jpeg bmp). All image MIME types start with image (for example: image/jpeg, image/bmp etc.).
  • void deleteFile(String fileLocation) deletes file if it exists.
  • List<String> getImagesFromLocation(String location) gets list of file names from absolute path (location) where images are stored. It doesn’t check if those files are images, so that folder needs to be clean (only images).
  • String getImageName(Part image) gets image name from Part interface. First it gets “content-disposition” header and it splits it to get key/value elements (example of header: form-data;name=”form:file”;filename=”some_image.jpg”). Then it looks for “filename” key and it returns it’s value prepended with UUID. UUID (Universally unique identifier) is a random 128 bit number written in certain format. It is used as a prepend because there could be images with the same name in folder where we keep images in.

package com.pro9ramming;

import java.io.File;
import java.util.*;
import javax.activation.MimetypesFileTypeMap;
import javax.servlet.http.Part;

public class FileUtil {
	public static Boolean uploadedFileIsImage(String imageLocation) {
        File f = new File(imageLocation);
        MimetypesFileTypeMap mtftp = new MimetypesFileTypeMap();
        mtftp.addMimeTypes("image png tif jpg jpeg bmp");
        String mimetype = mtftp.getContentType(f);
        String type = mimetype.split("/")[0];
        return type.equals("image");
    }
	
	public static void deleteFile(String fileLocation){
		File f = new File(fileLocation);
		if(f.exists())
			f.delete();
	}
	
	public static List<String> getImagesFromLocation(String location) {
		File f = new File(location);
		ArrayList<String> images = new ArrayList<String>(Arrays.asList(f.list()));
		return images;
	}
	
	public static String getImageName(Part image) {
		String[] arr = image.getHeader("content-disposition").split(";");
		for (String content : arr) {
			if (content.trim().startsWith("filename"))
				return UUID.randomUUID().toString() + "_" + content.substring(content.indexOf('=') + 1).trim()
								.replace("\"", "");
		}
		return null;
	}
}

Then create a managed bean that is going to be used for image uploading (let’s call it MainBean). Register it using @ManagedBean@SessionScoped annotations. MainBean has Part interface property (with getter and setter methods). MainBean has 3 methods (except getters and setters) :

  • void outputError(String messageStr) which gets FacesContext and creates FacesMessage which is outputted to “image-upload-form:image” location in .xhtml file.
  • List<String> getImages() gets images by using getImagesFromLocation() method from FileUtil class.
  • String upload() is an action method which is called by commandButton when user uploads it’s image. It gets image name (FileUtil.getImageName() method), creates streams (input and output) and writes image to absolute path. Then it validates if uploaded file is image (FileUtil.uploadedFileIsImage() method), and deletes the image if it is not, with message using FacesMessage from outputError() method. InputStream is stream from Part interface, and OutputStream is simple FileOutputStream. Input is written to output by using StreamUtil.WriteToOutputStream(input, output) static method.

package com.pro9ramming;

import java.io.*;
import java.util.*;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.Part;

@ManagedBean
@SessionScoped
public class MainBean {
	public static final String PATH = "C:/images/";
	private Part image;

	public Part getImage() {
		return image;
	}

	public void setImage(Part image) {
		this.image = image;
	}

	public String upload() {
		try {

			String imageName = FileUtil.getImageName(image);
			if (imageName == null)
				outputError("Image name not available.");
			String imageLocation = PATH + imageName;
			InputStream input = image.getInputStream();
			FileOutputStream output = new FileOutputStream(imageLocation);
			StreamUtil.WriteToOutputStream(input, output);
			input.close();
			output.close();
			if (!FileUtil.uploadedFileIsImage(imageLocation)) {
				outputError("Uploaded file is not an image.");
				FileUtil.deleteFile(imageLocation);
				return null;
			}
		} catch (Exception e) {
			e.printStackTrace();
			outputError("Error while uploading.");
			return null;
		}
		return "gallery";
	}

	private void outputError(String messageStr) {
		FacesContext context = FacesContext.getCurrentInstance();
		FacesMessage msg = new FacesMessage(messageStr);
		context.addMessage("image-upload-form:image", msg);
	}

	public List<String> getImages() {
		return FileUtil.getImagesFromLocation(PATH);
	}

}

That is background logic for uploading. There are 2 views (.xhtml files), let’s say index.xhtml (used for uploading) and gallery.xhtml (used for showing all uploaded images). Index.xhtml contains form with enctype=”multipart/form-data” attribute. Form contains:

  • h:inputFile with attribute value=”#{mainBean.image}”, which is part of JSF 2.2 standard.
  • h:message for showing FacesMessage messages associated with uploading process.
  • h:commandButton which calls upload() action method, when image file is selected.

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Image upload</title>
</h:head>
<h:body>
<h:form id="image-upload-form" enctype="multipart/form-data">
  <h:inputFile id="image" value="#{mainBean.image}"/><br />
  <h:message for="image" style="color:red"/><br />
  <h:commandButton value="Upload" action="#{mainBean.upload}"/>
</h:form>
</h:body>
</html>

Gallery.xhtml shows all images from folder where we keep them. It contains ui:repeat which shows all images by calling getImages() method. It also encapsultes h:graphicImage inside h:outputLink tags, so you can view actual size image, and not limited 300×200 size.

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Gallery</title>
</h:head>
<h:body>
<h2><h:outputText value="Gallery"/></h2>
<h:graphicImage value="/image/a1AXpew_460sa.gif" /><br />


<ui:repeat var="str" value="#{mainBean.images}">
<h:outputLink value="/JSFImageUpload/image/#{str}">
<h:graphicImage value="/image/#{str}" alt="Image not found" width="300" height="200"/><br /><br />
</h:outputLink>
</ui:repeat>

</h:body>
</html>

 

The final thing is creation of ImageServlet[4]. It uses doGet() method to retrieve requested image. It checks if image exists and it serves it by using FileInputStream and OutputStream from response object. Again writing from input to output stream is being done by using StreamUtil.WriteToOutputStream() method. Before serving, servlet sets “Content-Length” and “Content-Disposition” HTTP headers.

package com.pro9ramming;

import java.io.*;
import java.net.URLDecoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ImageServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		BufferedInputStream input = null;
		BufferedOutputStream output = null;
		try {
			String requestedImage = request.getPathInfo();

			if (requestedImage == null) {
				response.sendError(HttpServletResponse.SC_NOT_FOUND);
				return;
			}

			File image = new File(MainBean.PATH, URLDecoder.decode(
					requestedImage, "UTF-8"));

			if (!image.exists()) {
				response.sendError(HttpServletResponse.SC_NOT_FOUND);
				return;
			}

			String contentType = getServletContext().getMimeType(
					image.getName());

			if (contentType == null || !contentType.startsWith("image")) {
				response.sendError(HttpServletResponse.SC_NOT_FOUND);
				return;
			}

			response.reset();
			response.setBufferSize(StreamUtil.BUFFER_SIZE);
			response.setContentType(contentType);
			response.setHeader("Content-Length", String.valueOf(image.length()));
			response.setHeader("Content-Disposition", "inline; filename=\""
					+ image.getName() + "\"");

			input = new BufferedInputStream(new FileInputStream(image),
					StreamUtil.BUFFER_SIZE);
			output = new BufferedOutputStream(response.getOutputStream(),
					StreamUtil.BUFFER_SIZE);
			StreamUtil.WriteToOutputStream(input, output);

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (output != null)
				output.close();
			if (input != null)
				input.close();
		}
	}

}

And in your web.xml (WebContent/WEB-INF/web.xml) file, you need to register your ImageServlet:

<servlet>
    <servlet-name>imageServlet</servlet-name>
    <servlet-class>com.pro9ramming.ImageServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>imageServlet</servlet-name>
    <url-pattern>/image/*</url-pattern>
</servlet-mapping>

Now you can test your simple image gallery. For more information about certain parts of this tutorial, you can view references.

References :

Part interface 

File upload tutorial

BalusC Image Servlet

UUID reference

Check file type

Extend MimetypesFileTypeMap

]]>
Netbeans 8 criticism https://pro9ramming.com/netbeans-8-criticism/ Sat, 07 Feb 2015 13:33:18 +0000 http://pro9ramming.com/blog/?p=418 Continue reading Netbeans 8 criticism]]> I am working as .NET developer in Microsoft Visual Studio. Also I have some experience in Java (during my studies) generally by using Eclipse. For a long time I was fighting performance issues in Eclipse, than I decided to start using Netbeans, on some side projects. In the beginning everything was fine, I was amazed by functionalities, intellisense, code formatting, toolbars and general organization. I had some slight problems with setting up JBoss, but everything worked fine.

Then suddenly, out of nowhere Netbeans started to shutdown, in the middle of working. It usually happened when I press Enter or paste some code in the editor.  I am working on Windows 7, and haven’t found anything on forums about solution. It seems that those kind of problems Ubuntu users usually have. Than I tumbled on folder for Netbeans caching (C:\Users\Username\AppData\Local\NetBeans\Cache). When I deleted cached data (was over 80MB), Netbeans started working fine again, for few hours, until all cached data was back again. I also updated Netbeans regularly. Then I created a batch file that would remove cache, start Netbeans and than give that process a high priority. That lessened the number of fails. But still, every time I type a single line in Netbeans, I press Ctrl+S (that became a reflex), app would crash. I like Java, generally, but there is a lack of functional IDEs.

]]>
Perfect numbers https://pro9ramming.com/perfect-numbers/ Tue, 01 Jul 2014 17:43:27 +0000 http://pro9ramming.com/blog/?p=88 Continue reading Perfect numbers]]> Perfect number is a positive integer that is the sum of its proper positive divisors, that is, the sum of the positive divisors excluding the number itself. Equivalently, a perfect number is a number that is half the sum of all of its positive divisors (including itself).

For example, for interval between 0 and 10000, results are:
6
28
496
8128

Here is the code in Java:

public class example{
    public static void main(String[] args){
        for (int k = 1; k < 10000;k++){
            int sum = 0;
            for (int j = 1; j <= k/2; j++)
                if (k % j == 0)
                    sum += j;
            if(sum == k)
            System.out.println(k);    
        }
}
}

C++:

# include <iostream>
# include <math.h>

using namespace std;

int main()
{
    for (int k = 1; k < 10000;k++){
            int sum = 0;
            for (int j = 1; j <= k/2; j++)
                if (k % j == 0)
                    sum += j;
            if(sum == k)
            cout<<k<<endl;
        }
    system("pause");
}

Pascal:

program perfect_numbers;
uses wincrt;
var
i,k,j,s:integer;
begin
    for k:=1 to 10000 do
     begin
      s:=0;
      for j:=1 to (k div 2) do
       if (k mod j = 0) then
        s:=s+j;
         if s=k then
          writeln(k);
     end;
end.

 

]]>
JSF Client User-Agent data retrieve over RESTful web service https://pro9ramming.com/jsf-client-user-agent-data-retrieve-over-restful-web-service/ Sun, 16 Mar 2014 14:41:49 +0000 http://pro9ramming.com/blog/?p=422 Continue reading JSF Client User-Agent data retrieve over RESTful web service]]> Purpose of this tutorial is to get data about client’s user-agent over RESTful web service [1]. and show provided data in JSF page.

The process consists of 3 parts:

  • Get user-agent string from client’s HTTP request
  • Call web service and parse data about User Agent
  • Show data in JSF page to client

User-Agent string can be retrieved from HttpServletRequest object which can be accesses through FacesContext object:

FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getRequest();
String userAgentString = request.getHeader("user-agent");

Data is transfered in JSON format, parsing data is achieved through Jackson library [2]. API location is:

http://www.useragentstring.com/?getJSON=all&uas=USER-AGENT-STRING

Replace USER-AGENT-STRING with string retrieved in step one, for example:

Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.14

After calling web service (obviously over GET method), you’ll get JSON data, for example:

http://www.useragentstring.com/?getJSON=all&uas=Opera/9.80%20%28Windows%20NT%206.0%29%20Presto/2.12.388%20Version/12.14

which returns:

{  
   "agent_type":"Browser",
   "agent_name":"Opera",
   "agent_version":"12.14",
   "os_type":"Windows",
   "os_name":"Windows Vista",
   "os_versionName":"",
   "os_versionNumber":"",
   "os_producer":"",
   "os_producerURL":"",
   "linux_distibution":"Null",
   "agent_language":"",
   "agent_languageTag":""
}

Next step is reading those values and parsing them, using ObjectMapper from Jackson library [3]. First, for Jackson deserialization (or unmarshalling), class is needed. The UserAgent class looks like:

package com.pro9ramming.jacksontest;

import com.fasterxml.jackson.annotation.*;
 
public class UserAgent {
	@JsonProperty("agent_type")
	private String agentType;
	
	@JsonProperty("agent_name")
	private String agentName;
	
	@JsonProperty("agent_version")
	private String agentVersion;
	
	@JsonProperty("os_type")
	private String osType;
	
	@JsonProperty("os_name")
	private String osName;
	
	@JsonProperty("os_versionName")
	private String osVersionName;
	
	@JsonProperty("os_versionNumber")
	private String osVersionNumber;
	
	@JsonProperty("os_producer")
	private String osProducer;
	
	@JsonProperty("os_producerURL")
	private String osProducerURL;
	
	@JsonProperty("linux_distibution")
	private String linuxDistribution;
	
	@JsonProperty("agent_language")
	private String agentLanguage;
	
	@JsonProperty("agent_languageTag")
	private String agentLanguageTag;

//getters and setters

	@Override
	public String toString() {
		return "UserAgent [agentType=" + agentType + ", agentName=" + agentName
				+ ", agentVersion=" + agentVersion + ", osType=" + osType
				+ ", osName=" + osName + ", osVersionName=" + osVersionName
				+ ", osVersionNumber=" + osVersionNumber + ", osProducer="
				+ osProducer + ", osProducerURL=" + osProducerURL
				+ ", linuxDistribution=" + linuxDistribution
				+ ", agentLanguage=" + agentLanguage + ", agentLanguageTag="
				+ agentLanguageTag + "]";
	}
	
	
}

Annotation @JsonProperty is used to specify properties used in serialization and make sure right JSON identifiers are used. Class property can have different name than JSON property. UserAgent class also has toString() method for showing data to client. After making the UserAgent class, retrieving and parsing data over ObjectMapper is simple:

ObjectMapper mapper = new ObjectMapper();
UserAgent userAgent = mapper.readValue(INPUT-STREAM , UserAgent.class);

You need to replace INPUT-STREAM with input stream from URL class. URL class is instantiated by forming URL encoded string through GET method:

String urlString = "http://www.useragentstring.com/?getJSON=all&uas="+ URLEncoder.encode(USER-AGENT-STRING, "UTF-8");
URL url = new URL(urlString);
//input stream in url.openStream()

Putting everything together:

public String getData(){
		try {
			ObjectMapper mapper = new ObjectMapper();
			String urlString  = "http://www.useragentstring.com/?getJSON=all&uas="+ URLEncoder.encode(getUserAgentString(), "UTF-8");
			UserAgent userAgent = mapper.readValue(new URL(urlString).openStream(),UserAgent.class);
			return userAgent.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "ERROR";
	}
	
	private String getUserAgentString(){
		FacesContext context = FacesContext.getCurrentInstance();
		HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getRequest();
		return request.getHeader("user-agent");
	}

Let’s say that managed bean is called UserAgentBean, so in the .xhtml file, you can specifty next line:

<h:outputText value="#{userAgentBean.data}"/>

That is going to call getData() method, which returns data from UserAgent toString() method. You can format your output as you want.

References:

[1] User-Agent API

[2] JSON processing library – Jackson

[3] Mkyong JSON parsing tutorial

]]>
Number pattern challenge https://pro9ramming.com/number-pattern-challenge/ Sat, 15 Feb 2014 04:43:27 +0000 http://pro9ramming.com/blog/?p=205 Continue reading Number pattern challenge]]> Given the following number representing a pattern:

2053 = 2^0 + 5^3 = 1 + 125 = 126

Note: ^ means exponent
Look above at the number “20”; in this sequence it represents 2 to the 0 power which is 1. The other number “53” represents 5 to the 3rd power which is 125. Then final answer is calculated by the sum of each term.

Given this number below:

342345820139586830203845861938475676
What is the answer using the above pattern?
Solution includes representing this number above as a string and sum of those powers of digits.
Solution is: 2517052

Pascal code:

program number_pattern;
uses wincrt;
var
s:string;
i:integer;
n:real;
function power(a,n:real):real;
begin
  if n=0 then
    power:=1
  else
    if a=0 then
      power:=0
    else
     if abs(n*ln(abs(a)))>87.498 then
       runerror(205)
     else
       if a>0 then
         power:=exp(n*ln(a))
       else
        if (a<0) and (frac(n)=0) then
          if odd(round(n)) then
            power:=-power(-a,n)
      else
            power:= power(-a,n)
       else
             runerror(207);
    end;
function numcheck(s:string):boolean;
var
  x:integer;
  begin
   numcheck:=true;
    for x:=1 to length(s) do
     if (ord(s[x])<48) or (ord(s[x])>57) then
      if s[x]<>'' then
       numcheck:=false;
  end;
function strtoint(s:string):integer;
var
   check:integer;
   i:integer;
  begin
   if numcheck(s) then
    val(s,i,check);
     strtoint := i;
end;
begin
s:='342345820139586830203845861938475676';
n:=0;
i:=1;
while (i<=(length(s)-1)) do
   begin
     n:=n+power(strtoint(s[i]),strtoint(s[i+1]));
     i:=i+2;
   end;
writeln(n:9:0);
end.

C++ code:

# include <iostream>
# include <cstdio>
# include <math.h>
# include <string>

using namespace std;


int strtoint(string s)
{
  int i,p,k,j,v; 
  string h[10]={"0","1","2","3","4","5","6","7","8","9"}; 
   bool b;
   p=1;
   b=false;
   if (s.substr(0,1)=="-") 
     {
       b=true;
       s=s.substr(1,s.length());
     }
     for(i=0;i<s.length()-1;i++)
       p=p*10;
     k=0;
   for (i=0;i<s.length();i++)
     {       
    for (j=0;j<10;j++)
      if (h[j]==s.substr(i,1))
      {
          v=j;    
      }
    k=k+v*p;
    p=p/10;
     }
   if (b==true) 
     return -k;
   else
     return k;
}

Java code:

package NumberPattern;

public class NumberPattern
{
    public static void main(String[] args)
    {
        String str_num = "342345820139586830203845861938475676"; //string to hold long number
        char[] str_num_array = str_num.toCharArray();
        long result = 0;

        //Loop through array list
        for (int i = 0; i < (str_num_array.length); i = i + 2)
          {
            double a = Double.valueOf(String.valueOf(str_num_array[i]));
            double b = Double.valueOf(String.valueOf(str_num_array[i + 1]));
            result = (long) (result + Math.pow(a, b));
          }
        System.out.println(result);
    }
}

 

]]>