Netbeans 6.8, good old woodstock!

October 30, 2009

Well, it seems that Netbeans 6.8 does not come with Visual Web/Woodstock

I suspect that Sun (Oracle) are planning to replace it with those really nice ADF components, brilliant but folks it just is not commercial in my view.

People like us who have been using Netbeans with Woodstock to build HUGE applications are left high and dry and can’t move forward or upgrade to the new version. The cost of us converting to the new components is just too great with no financial benefit. We had the same trouble with IceFaces when that came out.

Personally I would like to actually get DHTLMX components and tightly integrate them with Woodstock and Visual Web, using this combination of components we’ve built some really swish AJAX based web apps that run VERY fast.

When you have 300 components on a form, you cannot hope to do it manually and leaving us with a text only option with no layout facilities provides us with no alternative but to stay with Netbeans 6.7.

So here’s my plan.

I plan to develop a tool/plugin/thingy that will allow you to visually design JSP/JSF pages. It will be seperate from Netbeans so we don’t suffer with random upgrade blues.

 

 


FAST way of generating JSP pages using EJB’s to provide the data!

October 4, 2009

Ok firstly sorry I’ve not posted much but had a lot of personal issues.

Anyway – here’s the story, we were using the awesome DHTLMX components with JSP’s feeding the data but we could never get the speed up especially since our source database had 270,000 records or so (and increasing!). The server is a GlassFish server by the way.

So basically the woodstock page replaced the DHTLMX combo boxes, and grid by feeding from JSP’s that opened a database in the standard way. Which is SLOOWWW.

By accident I found that moving the actual routine to an ejb with an entity manager made the code run about a million times faster. In fact when one of the customer’s date entry people tried it they nearly fell off their chair as it was so much faster than their existing system.

This technique can be used with just about any application to call a routine and return data, but it must be java.! Note I’m not a fan of XML because I think it gives back a whole load more data than it needs! But some of the components need it! :-)

Ok – so 3 teirs.

JSP PAGE <—> EJB Remote Interface <—> EJB

Here’s the JSP page that generates the XML in the WAR project (web application)

<?xml version="1.0" encoding="ISO-8859-1"?>
<%@ page contentType="text/xml;charset=ISO-8859-1" %>
<%@ page import = "java.sql.*" %>
<%@ page import = "javax.naming.Context" %>
<%@ page import = "javax.naming.InitialContext; "%>
<%@ page import = "PHJ.JobManagerRemote.*" %>
<%

 PHJ.JobManagerRemote jobManagerBean=null;
 try {
 Context c = new InitialContext();
 jobManagerBean=(PHJ.JobManagerRemote)c.lookup("java:comp/env/JobManagerBean");
 } catch (Exception ne) {
 System.out.println("Could not find Job Manager Bean "+ne);
 }

 String sql = "SELECT TOP 40 tblAddressBook.AddrName, tblAddressBook.AddrNum, tblAddressBook.AddrCity, tblAddressBook.AddrCounty, tblAddressBook.ID ";
 sql=sql+ " FROM tblAddressBook ";
 sql=sql+" WHERE tblAddressBook.LastUsed>DATEADD (day,-60,GETDATE() )  ";

 if (request.getParameter("mask")!=null) {
 sql=sql+" and addrName like '"+(request.getParameter("mask").replace("'","''"))+"%' ";
 }
 sql=sql+" ORDER BY tblAddressBook.AddrName ";

// connect to database

 //  String connectionURL = "jdbc:sqlserver://" + db_ipp_addr + ":1433;databaseName=" + db_name;

 //  Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
 //

 out.println(jobManagerBean.CustomerAddressserverXML(sql));

%>

Look how tiny it is! :-)

Ok So – then I have an EJB in an enterprise applcation called JobManagerBean. In the remote code we have….

public  String CustomerAddressserverXML(String sSQL);

and in the EJB itself…

@Override
 public  String CustomerAddressserverXML(String sSQL) {

 String sSQLTemplate = sSQL;
 List results = null;
 Query q = em.createNativeQuery(sSQLTemplate, TblAddressBook.class);

 try {
 results = q.getResultList();
 } catch (Exception e) {
 return "<complete></complete>";
 }

 String sResult = "";
// output data in XML format
 sResult = "<complete>";
 String sThisFields="";
 TblAddressBook thisCustomer = null;
 for (int i = 0; i < results.size(); ++i) {
 thisCustomer= (TblAddressBook) results.get(i);
 sThisFields=thisCustomer.getAddrName();
 sThisFields=sThisFields+" "+thisCustomer.getAddrNum();
 sThisFields=sThisFields+" "+thisCustomer.getAddrCity();
 sThisFields=sThisFields+" "+thisCustomer.getAddrCounty();
 sThisFields=sThisFields+" - "+thisCustomer.getId();
 sResult = sResult + ("<option value=\"" + (thisCustomer.getAddrName().replace("&","&amp;")) + "\"><![CDATA[" +
 sThisFields + "]]></option>");

 }
 sResult = sResult + ("</complete>");

 return sResult;

 }

Simples!

In a sense ofcourse you could move ALL your JSP code into EJB’s and actually have ONE JSP for your whole web site!


Using Jasper Reports with Icefaces and Visual Web

April 20, 2009

Ok here’s how to do it.

Firstly you’ll need a Jasper Reports Engine Class.

Create a new class in your project.

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package PHJ;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.sql.ResultSet;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.FacesException;
import javax.faces.context.ExternalContext;
import net.sf.jasperreports.engine.JRExporter;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JRResultSetDataSource;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.export.JRPdfExporter;

/**
 *
 * @author paulc
 */
public class PHJJasperReportEngine {

        private databasesettings MyDB=new databasesettings();

    // private static final String PREFIX = "/WEB-INF/reports/";
    private static final String PREFIX = "";///faces/";
    /**
     * <p>Suffix to the resource name for compiled reports.</p>
     */
    private static final String SUFFIX = ".jasper";
    /**
     * <p>Valid content types for reports that we can produce.</p>
     */
    private static final String[] VALID_TYPES = {"text/html", // Standard HTML representation
        "application/pdf", // Adobe Portable Document Format
        "application/rtf"};

     public byte[] iceFacesjasperReport(String sBaseURL,String sSQL,String name, String type, Map params) throws IOException {
        URL url=null;
        ByteArrayOutputStream returnStream=new ByteArrayOutputStream();

        System.out.println(sBaseURL);
        try {
            url = new URI(sBaseURL+"/"+name+SUFFIX).toURL();
        } catch (URISyntaxException ex) {
            Logger.getLogger(PHJJasperReportEngine.class.getName()).log(Level.SEVERE, null, ex);
        }

             ResultSet data=null;
        try {
            data = MyDB.getDataFromMYSQL(sSQL);
        } catch (ClassNotFoundException ex) {
            System.out.println("Class not found "+ex);
        }
             if (data==null) {
                 System.out.println("Error in SQL "+sSQL);
                 return null;
             }

        // Validate that we recognize the report type
        // before potentially wasting time filling the
        // report with data

        boolean found = false;
        for (int i = 0; i < VALID_TYPES.length; i++) {
            if (VALID_TYPES[i].equals(type)) {
                found = true;
                break;
            }
        }
        if (!found) {
            throw new IllegalArgumentException("Invalid report type '" + type + "' requested");
        }

        // Look up the compiled report design resource
        InputStream stream = url.openStream();

        if (stream == null) {
            throw new IllegalArgumentException("Unknown report name '" + name + "' requested");
        }

        try {
            data.beforeFirst();
        } catch (Exception e) {
            throw new FacesException(e);
        }

        // Fill the requested report with the specified data
        JRResultSetDataSource ds = new JRResultSetDataSource(data);
        JasperPrint jasperPrint = null;
        try {

            jasperPrint = JasperFillManager.fillReport(
                    stream, params, ds);

        } catch (RuntimeException e) {
            System.out.println(e);
            throw e;
        } catch (Exception e) {
            System.out.println(e);
            throw new FacesException(e);
        } finally {
            try {

                stream.close();
            } catch (IOException e) {
            }
        }

        // Configure the exporter to be used, along with the custom
        // parameters specific to the exporter type
        JRExporter exporter = null;

         // PersistentFacesState response=(PersistentFacesState)econtext.getResponse();
        //FacesContext fcontext = FacesContext.getCurrentInstance();
        try {
          //  response.setContentType(type);
            if ("application/pdf".equals(type)) {
                exporter = new JRPdfExporter();

            //    response.setHeader("Content-Type", "application/download");
              //  response.setHeader("Content-Disposition", "attachment; filename=" + name + ".pdf");

                exporter.setParameter(JRExporterParameter.JASPER_PRINT,
                        jasperPrint);
                exporter.setParameter(JRExporterParameter.OUTPUT_STREAM,
                        returnStream);

            }
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new FacesException(e);
        }

        // Enough with the preliminaries ...
        // export the report already
        try {
            exporter.exportReport();
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new FacesException(e);
        }

        // Tell JavaServer Faces that no output is required
        return returnStream.toByteArray();

    }

        public static byte[] toByteArray(InputStream input) throws IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        byte[] buf = new byte[4096];
        int len = 0;
        while ((len = input.read(buf)) > -1) output.write(buf, 0, len);
        return output.toByteArray();
    }

}

Then create a new page. You then need to add an OUTPUT RESOURCE component. I do this in the JSP tab because it doesn’t have any properties.

  <ice:outputResource attachment="true" fileName="subcontractorsummary.pdf" id="pdf-button" label="Output to PDF" mimeType="application/pdf"
                            resource="#{FRIMICESUBCONTRACTORSUMMARY.pdfResource}"
style="height: 24px; left: 24px; top: 168px; position: absolute; width: 119px" type="button"/>

In this case the page is called FRIMICESUBCONTRACTORSUMMARY so you’ll need to change that to match.

Now in the Java backing bean.

    private Resource pdfResource;

    public Resource getPdfResource() {
        return pdfResource;
    }

    public void setPdfResource(Resource pdfResource) {
        this.pdfResource = pdfResource;
    }

    class MyResource implements Resource, Serializable {
        public String sURL;
        private String resourceName;
        private final Date lastModified;
        private ExternalContext extContext;
        private PHJJasperReportEngine thisEngine = new PHJJasperReportEngine();

        public MyResource(ExternalContext ec, String resourceName) {
            this.extContext = ec;
            this.resourceName = resourceName;
            this.lastModified = new Date();

        }

        /**
         * This intermediate step of reading in the files from the JAR, into a
         * byte array, and then serving the Resource from the ByteArrayInputStream,
         * is not strictly necessary, but serves to illustrate that the Resource
         * content need not come from an actual file, but can come from any source,
         * and also be dynamically generated. In most cases, applications need not
         * provide their own concrete implementations of Resource, but can instead
         * simply make use of com.icesoft.faces.context.ByteArrayResource,
         * com.icesoft.faces.context.FileResource, com.icesoft.faces.context.JarResource.
         */
        public InputStream open() throws IOException {
            try {
                // getrequestservletpath retruns the page url
                // getRequestContextPath=/CourierSystem

                HttpServletRequest thisRequest=(HttpServletRequest) extContext.getRequest();
                sURL="http://"+thisRequest.getServerName()+":"+thisRequest.getServerPort()+extContext.getRequestContextPath();
                Map param = new HashMap();

                /***********************************************/
                /* THIS IS THE BIT YOU NEED TO CHANGE FOR YOUR */
                /* REPORT - Make sure the filename.jasper is in*/
                /* the same place as your icefaces pages       */
                /* lastly, make sure the SQL matches           */
                /***********************************************/

                String sReportFileName="RPTCUSTOMERJOBSUMMARY";
                String sSQL = "SELECT * FROM TBLCUSTOMERS";

                /************************************************/
                return new ByteArrayInputStream(thisEngine.iceFacesjasperReport(sURL, sSQL, sReportFileName, "application/pdf", param));

            } catch (Exception e) {

                System.out.println("Error " + e);
            }

            return null;
        }

        public String calculateDigest() {
            return resourceName;
        }

        public Date lastModified() {
            return lastModified;
        }

        public void withOptions(Options arg0) throws IOException {
        }

    }

And then add to the init()  phase of the page.

 try {
            FacesContext fc = FacesContext.getCurrentInstance();
            ExternalContext ec = fc.getExternalContext();
            pdfResource = new MyResource(ec, "report.pdf");

        } catch (Exception e) {
            e.printStackTrace();
        }

Bingo!


One Line of code confirmation on a button – visual web

March 24, 2009

Here’s one of those teeny tips that saves a lot of building screens etc. Let’s say you have a Visual Web button that you want the user to confrim before it proceeds through to the actual code at the back end.

In the onClick javascript property simply add

return confirm(“Are you sure”);

Then when the user clicks the button if they click OK the system will carry on and submit to the back end, if not, it will simply do nothing. Ofcourse we could expand this to add other messages by putting a function in some javascript in the head tags and the call it from the onClick.


Further Ubuntu Intrests — is it a Mac? Is it Vista?

February 28, 2009

Well it’s been a few days since I defected from the dictatorship of Windows Vista to Ubuntu – I do have to confess going back into Windows once. But that was just to get a document – I’ve not configured openoffice to read Office 2007 docs.

My Ubuntu now looks like a Mac, I have always loved those “scrolly bar at the bottom” thing that macs have. and I was delighted to find not one but TWO of them for Ubuntu.

Everything works faultlessly. Including a printer we have at work which would not install under Windows Vista without crashing the spooler whenever you went to Print. Not only did Ubuntu find the  printer, it correctly identified it, installed the driver and worked out of the box. Actually much better than windows Vista did.

There seems to be an interesting passion amongst Ubuntu users. There’s a strange feeling you’ve just got your computer back. All my apps are still running about 5 or 6 times faster than under windows. Partly because Ubuntu is running in 64 bit on here – and unlike Windows still runs all the 32 bit apps like Second Life seamlessly.

I’m feeling slightly silly though because I was working with Ubuntu 6.10 over a year ago – it was fine but you had to be a programmer to use it. Now I reckon it’s an IDEAL platform for anyone – especially with  the ability to change it to look how YOU want and not be dictated by the OS.

What was strange was when I went on to the Canal World IRC I use a lot to find I wasn’t the only one who has been redeemed.

Freedom is a nice feeling.


The return to UBUNTU!

February 26, 2009

I made a radical decision with my team today.

I used to live on UBUNTU and only use Windows for things that wouldnt work under Ubuntu.

Recently my latest new developer was singing Ubuntu’s praises so I thought I’d go back for a revisit.

Netbeans runs in Ubuntu about 50 times faster than Windows. My machine under ubuntu has got a new lease of life.

- The graphics are astounding – I installed the compiz package.
- We used some sort of install that ran under windoze and creates a host folder with all my windows stuff. – This meant I could just load up and work on the netbeans projects from my windows directory.
- The install of ubuntu including all the setting up only took a couple of hours, most of the stuff was installed automatically.
- I had problems with VPN’s not connecting but that was quickly fixed

I can’t see myself returning to Windows any time soon, I simply don’t see the point.

I have got all the developers moving to Ubuntu now as it is simply better than Windows for development of java apps.


Icefaces Good news and Bad News!

February 25, 2009

NEW RELEASE CANDIDATE

You may have remembered that I wrote about Icefaces tabset not working in NetBeans.. A new release is out (Release Candidate).

USING COMPONENTS ON A LAYOUT PANEL AND BEING ABLE TO LAY THEM OUT!

Well the goodnews is that you can now see components you drag and drop on to the tab set or layout panel.

However laying out is nigh on impossible. That was until I realised that when you drag and drop components to the page or a layout box of any  type, icefaces (or visual web) doesn’t assign a style to it – this may be by design, but by setting the components style to

position:absolute

I am then able to move and position them around the screen.

THE TABSET COMPONENT

However, the tabset itself is more complicated.

The tabset is made up of  TABS (which are some form of layout), with PANELLAYOUTS as a child under each tab. The panellayout, don’t ask me why is set to inherit it’s position from the parent and this seems to drive it crazy.

To make it so you can layout components on the tabset:-

In the style to the panellayout style

height: 500px; left: 12px; top: 35px; position: absolute; width: 800px

You’ll notice that the tab immediately shrinks in size to just the top – don’t worry about that – it will still work.

Now each component use the above “trick” of setting the style of the components to position:absolute and you are done.


Great Bug Tracking Software

February 23, 2009

We’ve been looking around at bug tracking software for our ever growing dev. team.

Found this. It’s BRILLIANT http://www.thebuggenie.net/ and free although we will look to adding it to our supported software after a trial.


Not wishing to sound like Victor Meldrew but….

February 9, 2009

I don’t beleive it.

Finally we get our selves migrated all the way to netbeans 6.5 and then we discover that the icefaces plugins which don’t work with 6.1 don’t work properly with 6.5.

The problem is that if you use any of the panels Like the tab control you drop controls on the tab and they just dissappear.

We *ARE* considering buying Icefaces support but actually I think they need to get it working first, I mean you wouldn’t buy a car if only half of it worked would you?


Using Jasper Reports with Visual Web in Netbeans 6.5

February 5, 2009

Firstly Infragistics let us down – you can only use Infragistics for JSF with Netbeans 5.5 (Although the website just sasy “NETBEANS”) ,… Refund please.

So our requirements:-

Netbeans 6.5
Jasper Reports
Visual Web – Woodstock/Icefaces

1. DO NOT INSTALL the Jasper Reports Plugins into Netbeans 6.5 – it breaks Visual Web
2. to Edit Reports use the stand alone Jasper Reports applciation

Secondly we need to add Jasper Reports ENGINE only to the Netbeans project so that we can run the jasper reports without upsetting visual web.

Now we can install the icefaces plugins and use them with our project.

To do this, simply download the Jasper Reports JAR file and then create a library “JasperReports” and add it to your web project – this will give you the support you need.

Save your reports into the WEB folder and then use the other code I have on this blog to execute the reports you create in your external IReport application.

Important: http://facestutorials.icefaces.org/tutorial/woodstock/PortingGuidePart1.html < Read this first before adding icefaces to your project.

 Also you’ll find this 2 page crud useful as it contains both Icefaces and JSP pages. http://facestutorials.icefaces.org/tutorial/woodstock/TwoPageCrudTable_Part2.zip

 Page Locations

Your old JSP pages (Woodstock) will be located at http://localhost:8080/Project-war/faces/pagename.jsp

IceFaces Pages are at http://localhost:8080/Project-war/pagename.iface  

You will also find your project runs index.html which you should redirect to where you want by changing it to:-

<meta http-equiv=”refresh” content=”0;url=faces/Page1.jsp”>