5.16.2014

According to androidannotations.org in order to add support of android annotations to your Android Studio project using Gradle you need to perform a few simple steps. These steps are described on this page - https://github.com/excilys/androidannotations/wiki/Building-Project-Gradle

But as I discovered this is not so simple as it is described. Once you perform all the steps from the above instruction, you will be available to use annotations in the source code. Moreover, gradle sync process will be successful. But as soon as you decide to run your project on some device or on emulator you will be surprised. That configuration of the gradle won't be enough. 

Probably you will face the error message like: "Could not find the AndroidManifest.xml file, going up from path ..."

In order to fix this error you need to apply the following 'dirty hack' in your build.gradle file:

applicationVariants.all { variant ->
        //  println "create folder for androidannotations:  ${aptOutput}"
        aptOutput = file("${project.buildDir}/source/apt_generated/${variant.dirName}")
        android.sourceSets[getSourceSetName(variant)].java.srcDirs += aptOutput.getPath()
        variant.javaCompile.doFirst {
            aptOutput.mkdirs()
            variant.javaCompile.classpath += configurations.androidannotations
            variant.javaCompile.options.compilerArgs += [
                    '-processor', 'org.androidannotations.AndroidAnnotationProcessor',
                    '-AandroidManifestFile=' + variant.processResources.manifestFile,
                    '-s', aptOutput
            ]
        }
        variant.javaCompile.source = variant.javaCompile.source.filter { p ->
            return !p.getPath().startsWith(aptOutput.getPath())
        }
    }

The complete build.gradle file looks like the following for me:

buildscript{
    repositories{
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.9.+'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.1'
    }
}

apply plugin: 'android'
apply plugin: 'android-apt'
ext.AAVersion = '3.0.1'
ext.daggerVersion = '1.0.0';

configurations {
    apt
    androidannotations
    androidannotations.extendsFrom(compile)
}

repositories{
    //There is the issue with local maven repositories
    //https://code.google.com/p/android/issues/detail?id=63908
    //bug in Gradle with local maven repo
    //as workaround, instead of the mavenLocal() the below line can be used
    maven {   url "/home/deezzel/.m2/repository" }
    mavenCentral()
}

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.3"

    defaultConfig {
        minSdkVersion 10
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }

    sourceSets {
        main {
            manifest.srcFile 'src/main/AndroidManifest.xml'
            java.srcDirs = ['src/main/java']
            resources.srcDirs = ['src/main/res']
        }
    }

    applicationVariants.all { variant ->
        //  println "create folder for androidannotations:  ${aptOutput}"
        aptOutput = file("${project.buildDir}/source/apt_generated/${variant.dirName}")
        android.sourceSets[getSourceSetName(variant)].java.srcDirs += aptOutput.getPath()
        variant.javaCompile.doFirst {
            aptOutput.mkdirs()
            variant.javaCompile.classpath += configurations.androidannotations
            variant.javaCompile.options.compilerArgs += [
                    '-processor', 'org.androidannotations.AndroidAnnotationProcessor',
                    '-AandroidManifestFile=' + variant.processResources.manifestFile,
                    '-s', aptOutput
            ]
        }
        variant.javaCompile.source = variant.javaCompile.source.filter { p ->
            return !p.getPath().startsWith(aptOutput.getPath())
        }
    }
}

def getSourceSetName(variant) {
    return new File(variant.dirName).getName();
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
//    compile 'com.android.support:appcompat-v7:19.+'
    compile 'com.t4soft:ExternalWidget:0.1'

    apt "org.androidannotations:androidannotations:${AAVersion}"
    compile "org.androidannotations:androidannotations-api:${AAVersion}"
    apt "com.squareup.dagger:dagger-compiler:${daggerVersion}"
    compile "com.squareup.dagger:dagger:${daggerVersion}"

    compile 'com.actionbarsherlock:actionbarsherlock:4.4.0@aar'
    compile 'com.android.support:support-v4:19.0.+'
}

The changes to add support of android annotations are in bold.

Hope this will help people who faced the same issue.

6.16.2013

I think many people (who is interested in the J2EE developing) faced the situation when after deploying and running the project you see something like this in the address bar:
http://localhost:8080/Yourproject-war/
This article will be useful for those who want to rid of the root context and port defining in the address bar. So in the end of the article you will achieve this:
http://localhost
Let's start from the simplest part - removing root context from the address bar.  In order to not show "Yourproject-war" part you can simply just open the Glassfish Admin Console (http://localhost:4848), go to the Configurations -> default-config -> Virtual Servers -> server section and set your project as the Default Web Module. That is all. Now you can access your deployed project using this link:
http://localhost:8080
Now I will describe more difficult part - how to use 80 port instead of 8080 for Glassfish. As you may know, non-root users can not use ports from the range < 1024. In order to assign 80 port for Glassfish you can use two options: install a glassfish as a root or use workaround that I will describe.

Let's begin.

I soppose that Glassfish server is already installed on your system. If not - please install it (you just need to download and unzip the archive).

In order to use 80 port we will use an utility called "authbind". Authbind lets you bind ports without beeing root. So we need to install authbind first and create a dummy file, to grant access to the user you would like to.
// first install authbind
sudo apt-get install authbind
// now create a dummy file which tells autbind who can access port 80
touch /etc/authbind/byport/80
chmod 500 /etc/authbind/byport/80
// change glassfish to your personal glassfish user or user that you are using every day :)
chown your_user /etc/authbind/byport/80
For me, for example, the command was look like this:
chown deezzel /etc/authbind/byport/80
Now you need to create the /etc/init.d/glassfish file and put the following content into it:

#! /bin/sh

#path to the glassfish directory
GLASSFISHPATH=/home/glassfish/glassfish/bin
case "$1" in
start)
echo "starting glassfish from $GLASSFISHPATH"
#domain1 - this is your configured domain for glassfish
sudo -u your_user authbind --deep $GLASSFISHPATH/asadmin start-domain domain1
;;
restart)
$0 stop
$0 start
;;
stop)
echo "stopping glassfish from $GLASSFISHPATH"
sudo -u your_user authbind --deep $GLASSFISHPATH/asadmin stop-domain domain1
;;
*)
echo quot;usage: $0 {start|stop|restart}"
exit 3
;;
esac

At this step you are done.

Now you can start|stop|restart glassfish from the /etc/init.d/ directory as the service. Moreover, now
Glassfish is listen port 80 and you are able to access your deployed project via the link:
http://localhost
Now you can buy a domain name and use it for your project to access it through the WWW.

Please feel free to ask any questions or let me know if you find a mistake. Thanks. 

6.09.2013

In this short article I will show how to insert the line break inside the Primefaces component's value.

Let's imagine that we need to insert the line break in the value of the column in <p:dataTable>. 

The simple code without line break:

<p:dataTable var="val" value="#{testMB.list}" paginator="true" rows="10" paginatorPosition="bottom" editable="true">
<p:column style="width:7%" headerText="Column1">
      <p:cellEditor>
            <f:facet name="output"><h:outputText value="#{val.val1}"/></f:facet>
       </p:cellEditor>
</p:column>
...
</p:dataTable>


So, as you can see, I got <h:outputText> value from the managed bean. This value is one-line string. 
Now we need to put some text in this value, but after the break. In this case we need to use escape charackter "&#10;". Also in order to accept this charackter we need to set "false" for the "escape" property and use "white-space:pre-line;" CSS property.

<p:dataTable var="val" value="#{testMB.list}" paginator="true" rows="10" paginatorPosition="bottom" editable="true">
<p:column style="width:7%" headerText="Column1">
      <p:cellEditor>
            <f:facet name="output"><h:outputText style="white-space:pre-line" escape="false" value="#{val.val1} &#10; 2013-06"/></f:facet>
       </p:cellEditor>
</p:column>
...
</p:dataTable>

That is all. Now you will see that "2013-06" value is printed from the new line.

5.03.2013

I have faced the issue with the <p:dataTable> when using rowEdit ajax event. Firstly, I tried to google some information regarding this and found out that many people faced the same issue.

The issue was in the following: when I try to edit row in the dataTable, all is going well. But when I try to save the changes, the new value doesn't retrieve and new value has not been saved.

The listener for the dataTable is defined in the following way:

<p:ajax event="rowEdit" listener="#{diarylMB.editRecord}" update="@this"/>

The function editRecord from managed bean:


public void editRecord(RowEditEvent event){
        Diary updated = (Diary) event.getObject();
        diaryService.edit(updated);
    }

event.getObject() retrieves the new value from the dataTable and edit() updates the record in the database.

But this code didn't work for me. event.getObject didn't retrieve the new data and as the result the record was not updated.

So, the main problem is that getObject() retrieves for some reason an old data.

Let's take a look at this line:

                                    <p:dataTable var="diary" value="#{diarylMB.lstDiary}" paginator="true" rows="10" paginatorPosition="bottom" editable="true">

The list displayed in the dataTable is getting in the getLstDiary function. This is a simple getter that retrieves the list of diary records from the database using the service class:

lstDiary = (List<Diary>) diaryService.getAll(usrMB.getCurrentUser());

So, this data always retrieves from the database and that is why getObject() returned an old value ( actually the value from the database). In order to fix this issue I have implemented the simplest checker:


if (lstDiary == null){
            lstDiary = (List<Diary>) diaryService.getAll(usrMB.getCurrentUser());
        }
        return lstDiary;

That is all. So, firstly, before submitting bug to the PrimeFaces, please check your code ;)

4.27.2013

In the previous post I told about how to upload file(image) to the database in J2EE application. Now I want to tell how to show this image on page. My toolkit is the same. So i'll use the Primefaces library for the UI.

A little bit another situation, we need to view the products in the Market. I decided to write a little example, that will show the name, image and description on the page. Other information can be retrieved in the same way. So... let's begin.

The part of the .xhtml page that responsible for the viewing of the information:

<h:form id="product-form">
                                <p:dataGrid var="product" value="#{marketMB.lstProducts}" columns="3"  
                                            rows="12" paginator="true" paginatorPosition="bottom">
                                    <p:panel header="#{product.name}" style="text-align:center">
                                        <h:panelGrid columns="1" style="width:100%">  
                                            <h:graphicImage value="ImageDisplay?product_id=#{product.id}" width="150px" height="150px"/>   

                                            <h:outputText value="#{product.description}" />    
                                        </h:panelGrid>  
                                    </p:panel>
                                </p:dataGrid>

The MarketManagedBean:

@ManagedBean(name="marketMB")
@SessionScoped
public class MarketManagedBean implements Serializable{
    @EJB
    private ProductService productService;
    
    private List lstProducts;
    
    private Product selectedProduct;
    
    public void MarketManagedBean(){}
    
    public void setListOfProducts(){
        lstProducts = (List) productService.getAll();
    }


    /**
     * @return the lstProducts
     */
    public List getLstProducts() {
        setListOfProducts();
        return lstProducts;
    }

    /**
     * @param lstProducts the lstProducts to set
     */
    public void setLstProducts(List lstProducts) {
        this.setLstProducts(lstProducts);
    }

    /**
     * @return the selectedProduct
     */
    public Product getSelectedProduct() {
        return selectedProduct;
    }

    /**
     * @param selectedProduct the selectedProduct to set
     */
    public void setSelectedProduct(Product selectedProduct) {
        this.selectedProduct = selectedProduct;
    }
}
As you can see I am trying to retrieve the list of products using the Service class:

public List getAll() {
        return (List) em.createNamedQuery("Product.findAll").getResultList();
    }
The NamedQuery is described in the Entity class:

@NamedQuery(name = "Product.findAll", query = "SELECT p FROM Product p")
Now let's consider this line:
<h:graphicImage value="ImageDisplay?product_id=#{product.id}" width="150px" height="150px"/>   
The ImageDisplay is the name of the servlet. This servlet is responsible for the image retrieving from the database for the particular product. "product_id" is an Http parameter and it will contain the id of the product. As the result, servlet will retrieve the image from the database for the particular product using the HttpSession parameter "product_id". The code of the servlet:

public class ImageDisplay extends HttpServlet{
    /**
     *
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void doGet(HttpServletRequest request,
            HttpServletResponse response)
            throws ServletException, IOException {
        Statement stmt = null;
        ResultSet rs;
        InputStream sImage;
        try {
 
            String id = request.getParameter("product_id");
            System.out.println("inside servlet–>" + id);
 
            Connection con = Database.getConnection();
            stmt = con.createStatement();
            String strSql = "select image from product where id='" + id + "' ";
            rs = stmt.executeQuery(strSql);
            if (rs.next()) {
                byte[] bytearray = new byte[1048576];
                int size = 0;
                sImage = rs.getBinaryStream(1);
                response.reset();
                response.setContentType("image/jpeg");
                while ((size = sImage.read(bytearray)) != -1) {
                    response.getOutputStream().
                            write(bytearray, 0, size);
                }
            }
 
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
As you can see servlet is getting the parameter "product_id" from the Http Request and then it is using in the query to the database.
Then we need to transform retrieved data to the image. The last thing that needed to be considered is web.xml file:

<servlet>
        <description></description>
        <display-name>ImageDisplay</display-name>
        <servlet-name>ImageDisplay</servlet-name>
        <servlet-class>beans.mbeans.ImageDisplay</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ImageDisplay</servlet-name>
        <url-pattern>/ImageDisplay</url-pattern>
    </servlet-mapping>

In this "how to" I'll tell about the process of the uploading file to the database in J2EE project. My toolkit is consist of Netbeans IDE, Glassfish web server, UI library - Primefaces. Let's consider the example with the internet market.

Let's imagine that you have such an entity as a Product. The fields that described in the entity class are: name, description, price and image.

For now the main objective is to add Product to the database.
The part of the .xhtml page that describes the adding to the database:

<h:form enctype="multipart/form-data">

            <p style="font-family: 'Yanone Kaffeesatz';">Choose image for the product</p>
                     <p:fileUpload showButtons="false"
                                value="#{addProductMB.input_file}"
                                mode="simple"   
                                sizeLimit="10000000"   
                                allowTypes="/(\.|\/)(gif|jpe?g|png)$/"/>  
                      <br/>
                      <p style="font-family: 'Yanone Kaffeesatz';">Type the name of the product</p>
                      <p:inputText value="#{addProductMB.curproduct.name}"/>
                      <br/><br/>
                      <p style="font-family: 'Yanone Kaffeesatz';">Select the category of the product</p>
                      <p:selectOneMenu value="#{addProductMB.category_name}">
                           <f:selectItem itemLabel="Select One" itemValue="" />  
                           <f:selectItems value="#{addProductMB.category_list}" />
                      </p:selectOneMenu>                             
                      <br/><br/>
                      <p style="font-family: 'Yanone Kaffeesatz';">Type the description of the product</p>
                      <p:inputTextarea value="#{addProductMB.curproduct.description}" cols="50" rows="10"/>
                      <br/><br/>
                      <p style="font-family: 'Yanone Kaffeesatz';">Specify the price of the product</p>
                      <p:spinner min="0" max="2000" maxlength="5" value="#{addProductMB.curproduct.price}"/>
                      <br/><br/>
                      <p:commandButton ajax="false" style="font-family: 'Yanone Kaffeesatz';" 
                                       value="Add product" action="#{addProductMB.addProduct()}"/>
</h:form>
As you can see, I am using the addProductMB as backand bean class. The full name of this class is addProductManagedBean. Let's deal with it:
@ManagedBean(name="addProductMB")
@ViewScoped
public class AddProductManagedBean {
    
    @EJB
    private ProductService productService;
    @EJB
    private CategoryService categoryService;
    private Product curproduct = new Product();
    private UploadedFile input_file;
    private List<String> category_list;
    private String category_name;
    
    public AddProductManagedBean(){}

    private List<String> getCategoryListNames(){
        setCategory_list(categoryService.getCategoryNames());
        return getCategory_list();
    }
    
    
    
    /**
     * @return the productService
     */
    public ProductService getProductService() {
        return productService;
    }

    /**
     * @param productService the productService to set
     */
    public void setProductService(ProductService productService) {
        this.productService = productService;
    }

    /**
     * @return the curproduct
     */
    public Product getCurproduct() {
        return curproduct;
    }

    /**
     * @param curproduct the curproduct to set
     */
    public void setCurproduct(Product curproduct) {
        this.curproduct = curproduct;
    }
    
    public void addProduct(){
        if ((curproduct.getName() != null)||(curproduct.getDescription()!=null)){
            String filename = input_file.getFileName().toString();
            String contType = input_file.getContentType();
            String name_cat = this.category_name;
            if (input_file!=null){
            curproduct.setImage(this.input_file.getContents());
            }
            curproduct.setCategory(categoryService.getByName(category_name));
            productService.create(curproduct);
        }
    }

    /**
     * @return the input_file
     */
    public UploadedFile getInput_file() {
        return input_file;
    }

    /**
     * @param input_file the input_file to set
     */
    public void setInput_file(UploadedFile input_file) {
        this.input_file = input_file;
    }

    /**
     * @return the categoryService
     */
    public CategoryService getCategoryService() {
        return categoryService;
    }

    /**
     * @param categoryService the categoryService to set
     */
    public void setCategoryService(CategoryService categoryService) {
        this.categoryService = categoryService;
    }

    /**
     * @return the category_name
     */
    public String getCategory_name() {
        return category_name;
    }

    /**
     * @param category_name the category_name to set
     */
    public void setCategory_name(String category_name) {
        this.category_name = category_name;
    }

    /**
     * @return the category_list
     */
    public List<String> getCategory_list() {
        category_list = categoryService.getCategoryNames();
        return category_list;
    }

    /**
     * @param category_list the category_list to set
     */
    public void setCategory_list(List<String> category_list) {
        this.category_list = category_list;
    }
}
The most interesting part of this code is function addProduct(). Let's describe it line-by-line. Firstly, we need to check if the Name and Description were entered on the page. The next step is to retrieve the image that was chosen on the page and upload it to the database. Uploading of the new product's content is proceeding by the entity manager through the service class:

public void create(T entity) {
        getEntityManager().persist(entity);
    }

4.19.2013

In order to describe the picture in detail we need at least two .xhtml pages and one backend bean.

Let's consider that we have two pages with such a content (use any code you wish instead of <...>. I will describe only navigation effect)
 <html>
<h:head>...</h:head>
<h:body>
... 
<a href="index.xhtml">Homepage</a>
<a href="publications.xhtml">Publications</a>
...
</h:body>
<html>

Now we need to transform these lines in something that will show us on wich of the pages we are: Homepage or Publications (e.g.).

Let's create the managed bean, that will contain the following:

@ManagedBean (name="mainMB")
@SessionScoped
public class MainManagedBean {
 
    private String url;
 
    public void MainManagedBean(){}
    /**
     * @return the url
     */
    public String getUrl() {
        return url;
    }
    /**
     * @param url the url to set
     */
    public void setUrl(String url) {
        this.url = url;
    }
 
    public String getCurrentPage(){
        url = ((HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest()).getRequestURI();
        if (url.contains("index.xhtml")){
            return "index";
        } else
return "publs";
}
What actions does the getCurrentPage do? It is simple, in this method we are getting our current URI and checking its content. If its content is like index.xhtml, we need to return "index" string. In another case we need to return "publs" string.
Let's edit the pages:
<html>
<h:head>...</h:head>
<h:body>
... 

 <c:if test="#{mainMB.currentPage!='index'}">
   <a href="index.xhtml">Homepage</a>
</c:if>
<c:if test="#{mainMB.currentPage=='index'}">
   <a style="color:red" href="index.xhtml">Homepage</a> 
</c:if>
<c:if test="#{mainMB.currentPage!='publs'}">
   <a href="publications.xhtml">Publications</a>
</c:if>
<c:if test="#{mainMB.currentPage=='publs'}">
 
   <a style="color:red" href="publications.xhtml">Publications</a> 
</c:if> 
...
</h:body>
<html>
So, that is all. For now you will see the indication of the current page in red color.


Subscribe to RSS Feed Follow me on Twitter!