tag:blogger.com,1999:blog-4534761042428144922009-02-21T03:11:40.888-06:00Moving to Java and PhobosMoving to the Java platform with a Phobos focus. Phobos is a great scripting alternative for those who are looking for a powerful open source scripting environment.Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.comBlogger26125tag:blogger.com,1999:blog-453476104242814492.post-16233648731679075542009-01-09T08:29:00.003-06:002009-01-09T08:46:30.230-06:00Sun Web Server 7 on Debian LennyI recently built and deployed two more web servers using Debian Lenny and Sun Web Server 7. Although Debian is not specifically supported by Sun, the web server installs and runs flawlessly. With Java tightly integrated with the web server, deploying and maintaining Java applications is a breeze. This makes hosting web sites extremely simple even for the smallest companies. With the integrated WebDav and Java, the only thing you need besides the web server is a mail server. This makes maintenance and security tidier, and the learning curve is quite small compared to other web servers such as Apache and IIS. I have used all three and would hate to have to use anything else now. If you are curious, give it a try. It is free to download.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-1623364873167907554?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com0tag:blogger.com,1999:blog-453476104242814492.post-57931382667772205702008-12-16T09:02:00.002-06:002008-12-16T09:09:04.592-06:00Phobos Version 0.6 Sun Web ServerThe latest version of Phobos is available at <a href="https://phobos.dev.java.net/v6/">https://phobos.dev.java.net/v6/</a>.<br /><br />I have deployed the empty war app to both Sun GlassFish Enterprise Server v3 Prelude and Sun Java System Web Server 7.0 Update 3 successfully.<br /><br />I hope to post more code samples soon!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-5793138266777220570?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com0tag:blogger.com,1999:blog-453476104242814492.post-26543035549144888182008-10-08T15:39:00.003-05:002008-10-08T15:45:13.891-05:00Phobos ProgressThe Phobos team began working on the next version of Phobos. The details are located at https://phobos.dev.java.net/v6/index.html. Although progress has been slow, the improvements are well thought out and valuable. I have several code examples available for posting and hope to put them starting next month as time permits. I have a few basic pieces of a webmail app I am putting together using Phobos and JQuery. I will post the code for free use sometime this winter hopefully.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-2654303554914488818?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com0tag:blogger.com,1999:blog-453476104242814492.post-72913906547792278682008-06-17T15:26:00.002-05:002008-06-17T15:54:23.023-05:00Phobos Production AppsSummer time is extremely busy for me and I do not get much chance to work with new technologies and projects. If only there were more hours in the day. . . <br /><br />It amazes me how long it takes to bring technology on line in a business environment. I have been working with Phobos for a while now and looking for ways to implement it in production environments. It will happen in the future, but with economic and business cycles, it will take a few years to move into. Businesses first have to decide to move. Then they have to test and start with small projects. Then the pace begins to accelerate. This cycle of moving to something new can take years even if the new system is better. Meanwhile, people judge open source projects by the size of the communities and software running on it. Sometimes there are people using the software and working with it, but it is not visible to the world. It does takes time to write about what you are doing with a particular project, but it is a way of giving back to those who have worked on the project. I encourage others to write a blog or you can share what you are doing with someone who writes a blog. It will help to foster interest in a project. <br /><br />Now if someone would pay me to write Phobos code . . . <br /><br />Until then, I must regulate the fun stuff to off hours. :-)<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-7291390654779227868?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com0tag:blogger.com,1999:blog-453476104242814492.post-46295129735570959762008-04-30T21:18:00.001-05:002008-04-30T21:18:44.889-05:00JavaScript On The WireI have been working on a website using Phobos, and it is interesting to <br>note some powerful features that are very subtle when using Phobos and <br>JavaScript in general compared to some other languages. One of these <br>features is what I have seen some call JavaScript on the Wire. This <br>means using JSON to transfer data around in your application. You can <br>read more about JSON at JSON.org. Now why is this powerful. In <br>JavaScript, it is powerful because JSON describes objects. Basically, <br>your data is described as an object, and you can pass it around to <br>different modules and functions without recreating it or destroying it.<p>To demonstrate, lets take a html form post. We can post that form to a <br>controller in Phobos. Inside that controller we can call a Phobos <br>library function to get our form field values with this line of code:<p>formFields = library.httpserver.parseRequestParameters();<p>formFields is now an object containing all of our form fields from our <br>html form. Let us suppose that we want to pass this on to a data <br>validation object which we have encapsulated as an object. We can do it <br>like this:<p>formFields = module.validateForm(formFields);<p>Now persist the data to the database with another module we have:<p>formFields = module.saveFormData(formFields);<p>Now use the model to pass the obeject back to the view to render the form:<p>model = formFields;<p>What we have just demonstrated is that we can take an object from some <br>input and pass it around all through our cycle of processing always <br>using the same object. Please do not forget that because we are using <br>JavaScript, we can add additional properties and methods to that object <br>anywhere in our cycle as well without affecting anything.<p>A good rule I have found is use to always pass data using JSON. This <br>not only makes coding easier, it also allows greater flexibility. If <br>you write a function which accepts one parameter it will get the job <br>done. However, if down the road you add a second parameter, now you <br>have some maintenance to do wherever that function is being called. <br>With JSON and passing objects, it doesn't matter. Just add a property <br>to the JSON object and the function doesn't care. It just accepts the <br>object with the extra property. Every other call to the function is <br>passing in an object with one less property. This rule makes for <br>flexible coding and less maintenance and broken code.<p>I am looking forward to see what will come out of Java One for Phobos, <br>although I will have to wait for the blogs and media as I am not able to <br>attend. While mostly using Phobos for web applications, I am interested <br>to see if Phobos will start up from the command line. Glassfish V3 has <br>options to run trimmed down, and light weight. If you can run Phobos in <br>a light weight Glassfish, it will open up some fun possibilities. <br>Because I do system maintenance, I can think of a few system scripts and <br>tools that would be nice to write in Phobos.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-4629512973557095976?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com0tag:blogger.com,1999:blog-453476104242814492.post-30059814534257260562008-04-11T09:32:00.004-05:002008-04-11T10:21:23.531-05:00Phobos Most Important Feature - It Stacks UpI was recently asked, why did you choose Phobos? It made me stop and ponder all of the other scripting technologies I looked at, and why I settled on learning, developing, and writing about Phobos. Besides the requirement of being open source, here is my short list of importance.<br /><br />1) It must be simple to use. Simplicity translates into more productivity.<br />2) It must be powerful. I do not want to reinvent the wheel for everything I need to<br /> do.<br />3) It must be based on a somewhat standard deployment infrastructure. Some projects <br /> are good at specific things, but once needs grow outside the original bounds, it <br /> becomes difficult to meet advanced needs.<br />4) The language must be easy to use.<br /><br />The best feature I find about Phobos is its simplicity. The way the infrastructure is laid out is incredibly simple, but powerful. There are minimum requirements to interface between the pieces, and yet the interfacing can be as complicated as you need it. You can abstract as much or as little as you want. Subclass as much or little as you want. Phobos is simple, but very flexible.<br /><br />The second feature of being powerful. This is simplistic. You do not get more powerful than the Java platform. With Phobos, Java object integration is as native as Java. If your a Windows programmer, it is as native as using COM or .Net objects. When you look at large enterprise applications, a great majority are running on Java. This power is available to you as a script writer. With this integration, power, and Java market share, pieces can be dropped right into Phobos. For example, if you need to accomplish a certain task like make a connection to a database, you do not need to find a Phobos specific example on how to do it. You can take any basic Java example and rewrite it using JavaScript and the Java objects. This means that every piece of Java code on the Internet is now a Phobos example. If you stop and think about it, that thought is pretty incredible for a scripting language. We can conclude that in order to use Phobos effectively, we do not need millions of developers to have years of experience using it and writing examples of how to get things done, because we already have that. You can become very productive immediately.<br /><br />Third. With the rapid pace of change in operating systems, servers, security and software, a solution based on a standard deployment platform is important. There are many good products out there, but if you invest years of development into an application, you want to be sure that it will run on the platforms of the future. Java containers and Java fill this need. They are standards based and deployed worldwide. Projects who maintain their own deployment infrastructure or app server, must change with the times. With deployment to a standard Java app server, we can be assured applications will run in the future.<br /><br />Fourth. The language must be easy to use. I do not want to compare the pros and cons of different languages, but I will say that JavaScript is everywhere because of the Web. Many solutions are trying to give developers tools to avoid writing JavaScript. With a debuggers now available in NetBeans and in FireFox, why not just write JavaScript for web applications?<br /><br />I recently saw an article touting Adobe's new AIR development server, DARE. It stated that <span style="font-style:italic;">this server would allow you to test AIR applications on your local machine. It would be as easy as changing a few lines of code and refreshing your browser. DARE will greatly increase web productivity and make it much easier to develop web applications.</span> Is this really cutting edge? Is that what they are saying? We have had that with PHP and ASP for years. Anyway, I am not going to rant, but I will say that Phobos and Netbeans have this as well. No need for compile or deployment, just a browser refresh, and you do not have to use proprietary technology.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-3005981453425726056?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com0tag:blogger.com,1999:blog-453476104242814492.post-9609931399024595182008-03-27T21:48:00.001-05:002008-03-27T21:48:13.692-05:00Phobos, DB Pooling And ConnectionsFor those who have followed my data examples in the past, and have tried <br>them out, here is a recent issue I ran across. I have designed what <br>some would call a data facad, crud module, business object. Whatever, <br>you want to call it, it handles all of the data access for a particular <br>table. I was testing this on my laptop from the Netbeans environment, <br>and every time a page was requested five times, the Phobos runtime would <br>go into an endless loop. However, when you stopped the run time, a null <br>pointer exception would be thrown on this line of code:<p>conn = <br>java.sql.DriverManager.getConnection("jdbc:apache:commons:dbcp:oConn");<p>What this line does, is in my previous data examples. After doing some <br>checking around on Google about Java data pooling, it finally dawned on <br>me that I was running out of connections. I was closing the <br>connections, but the code was not getting executed. Here is an example <br>of the offending code in the module method which is called.<p>return obj;<br>stmt.close();<br>rset.close();<br>conn.close();<p>The code is never run, because execution stops at the return statement. <br>Some might think this would be obvious, but this behavior is not the <br>same in an ejs file or controller. My assumption was that it would get <br>run, and so we should get the data back asap. We could the worry about <br>cleanup code. However, all cleanup code needs to be run before the <br>return statement. It should look like this.<p>stmt.close();<br>rset.close();<br>conn.close();<br>return obj;<p>Small change, but big results. If we abstract our data access into <br>modules, it is fast and easy to clean this up versus having it scattered <br>in scripts.<br>Below is an example of a method of the crud class. I will hopefully be <br>posting all of the code for the data layer soon.<p>Happy Coding!<p> var stmt = null;<br> var rset = null;<br> var strSql = null;<br> // oConn is the connection pool set in application startup<br> conn = <br>java.sql.DriverManager.getConnection("jdbc:apache:commons:dbcp:oConn");<br> strSql = 'SELECT * FROM article WHERE ARTICLE_PK = ?';<br> stmt = conn.prepareStatement(strSql);<br> stmt.setInt(1, articleId); // articleId is passed in<br> rset = stmt.executeQuery(); <br> // Call method used to generate a json object of record set <br> obj = this.generateJson(rset);<br> obj.status = true;<br> stmt.close();<br> rset.close();<br> conn.close(); //clean up<br> return obj;<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-960993139902459518?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com1tag:blogger.com,1999:blog-453476104242814492.post-21647276816816490172008-03-15T20:47:00.001-05:002008-03-15T20:47:51.080-05:00Sun Webserver on DebianRecently I needed to put together a web server for a few websites. The <br>hardware was put together on the cheap. It is amazing what you can get <br>with a few hundred dollars. The hardware consisted of a MSI motherboard <br>with an AMD dual core processor, two gig of ram and two sata hard <br>drives. All the hardware came in under $450.00. I installed the latest <br>version of the AMD64 Debian to run a headless system with software raid <br>1. I then installed Sun's web server which is available for free <br>without support. It also comes with 64 bit support for the AMD <br>processor. The only wrinkle I ran into during the install was that the <br>JDK that comes with the installation of the web server will not install <br>on Debian because of missing libraries. I worked around this by <br>installing the latest JDK from the Debian repository. I am using the <br>stable version so I did use apt pinning to pull that from the unstable <br>branch as some libraries are needed that are not in the stable branch. <br>I also installed Postgres 8.3 this way. Other than that, the install of <br>the web server went flawless. The start and stop scripts even appeared <br>to start the web server on system boot which was very nice, especially <br>since Debian is not officially supported by Sun. <p>After the install, web server maintenance was a breeze. I needed to <br>setup a few virtual hosts and I wanted them to be ip based. It took all <br>of about three minutes through the web interface. I looked at the Sun <br>web server a few years back and found the web interface to be somewhat <br>confusing. However, they have since redone the whole interface and it <br>is much more intuitive and straight forward. I found it very easy to <br>work with.<p>The web server also supports webdav out of the box. I decided to try <br>to allow users to change their files using webdav instead of setting up <br>an ftp server. This would trim one running process and also be one less <br>security detail to lock down. The webdav was easy enough to set up, but <br>I did have a slight problem getting the security to work properly. <br>However, a short trip to the Sun web server forum, where I received <br>several helpful answers almost immediately, solved the issue. <p>I chose to try Sun's web server over Apache because not being a long <br>time Linux guru, and needing extremely tight security on web systems in <br>todays environment, I felt much more comfortable with Sun's server. <br>With Apache, set up can be quite complicated and, in my opinion, it is <br>much easier to accidentally open up a security hole. It is too bad <br>Sun's marketing material bills the web server as best used for medium to <br>large installations, because it will work just as well for a small company.<p> One other thing I wanted to mention was what I was very impressed with <br>the speed of the server. It is fast at serving content up. I do not <br>claim to have benchmarks and what not, but coming from 32 bit hardware <br>and operating systems running IIS and SQL server, I was impressed. I am <br>sure it was a combination of the Linux kernel optimized for the <br>processor and then the web server optimized for the 64 bit chip, but the <br>speed is impressive nonetheless.<p>On a different note, when time permits, I will be trying out running a <br>Phobos app on Sun's web server. The web server is convenient over the <br>application server in the fact that it binds to port 80 and runs out of <br>the box as user nobody and has lots of virtual hosting tools. You can <br>use Glassfish to do the same thing, but of course it is not geared as <br>much for that purpose. Phobos could take the place of say asp or php on <br>a web server for a web host. A company could advertise web hosting <br>with server side javascript enabled out of the box with an open source <br>database.<p>I am happy to see Sun accepting the model they have for software as far <br>as licensing and support. Even though small companies may never want to <br>pay what a Sun support contract would cost them, I have found the Sun <br>employees on the forums to be most helpful. The more system admins and <br>developers that can use the software, the bigger ecosystem of free <br>support will be available out there on the web free of charge for small <br>users. With software, the better products doesn't always necessarily <br>win, it is the product that develops the largest user base for one <br>reason or another. Profits understandably must made, but is uncanny how <br>sometimes that profit will kill the product in the long run because <br>another product become more popular. I believe Sun is heading in the <br>right direction as far as growing their user base for their products and <br>I am happy to see it. Now if we could only get Solaris to run on dirt <br>cheap hardware . . .<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-2164727681681649017?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com8tag:blogger.com,1999:blog-453476104242814492.post-51856759858069077012008-02-20T20:58:00.001-06:002008-02-20T20:58:47.670-06:00Phobos Code and JavaI have been working on a site recently and doing some more with data <br>access. I was working on the problem of creating multiple records in <br>different data sources and having to combine them at a later date. I <br>also wanted a generic way to insert a record and get the record back <br>without having to try to get an auto-generated key back from different <br>drivers and databases. This of course led to the idea that I needed a <br>unique number. What is the best way to do this inside of Phobos? You <br>first might think of someway to do it in Javascript, but this is where <br>we would be wrong. This is where the prowess of the Java platform comes <br>in. We tap the power of Java from our scripting language to do some <br>heavy lifting for us. So how much code does it take?<p>key = java.util.UUID.randomUUID().toString();<p>That's it! Now it may not be as random as a GUID, but it will work for <br>almost all situations, especially on small projects. We just tap a Java <br>class to accomplish this for us. There are other Javascript server <br>applications out there, but with the Java underpinnings, Phobos is hard <br>to beat.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-5185675985806907701?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com0tag:blogger.com,1999:blog-453476104242814492.post-5663547153963864442008-01-23T21:53:00.001-06:002008-01-23T21:53:25.131-06:00More Phobos Data AccessA few months ago I was playing with some data access code and thought I <br>would publish it. One of the problems some people must solve is data <br>access to sources without a jdbc driver. I used Phobos to connect to a <br>Visual Foxpro database. The same technique should be able to be used <br>for an Access database or other data. The first example just shows a <br>driver connection. The second example shows a pooled connection using <br>Apache Commons. The module code for the pooling part is in a previous <br>blog. This means you can have a pooled data connection from Phobos to <br>just about any data source. This would not be possible with most Java <br>application servers, but since we are using our pooling objects provided <br>by Apache, we can accomplish a much greater variety of data access from <br>Phobos. Phobos is versatile and flexible.<p>Driver Example:<br>library.common.define(controller, "test", function() {<br> this.Test = function() {<br> this.onRequest = function() {<p> // Set up our connection by specifying the driver<br> java.sql.Class.forName="sun.jdbc.odbc.JdbcOdbcDriver";<br> // We are using the java odbc bridge with a VFP database<br> // You need a DSN set up on your machine and for VFP you<br> // only need to specify the DSN name. User & Pass are blank.<br> var con = new <br>java.sql.DriverManager.getConnection("jdbc:odbc:javafox","","");<br> // create a statement<br> stmt = con.createStatement();<br> stmt.setMaxRows(1);<br> // create the result set by executing the query<br> // You can specify properties for locking etc if you wish.<br> rs = stmt.executeQuery("select * from some table");<br> //Loop through the result set and make a json object<p> var rsJSON = "{rs: [";<br> var numcols = rs.getMetaData().getColumnCount();<br> while (rs.next()) { //Loop through record set<br> rsJSON += "{"; //resultet row<br> for (i=1; i<=numcols;i++) {<br> rsJSON += rs.getMetaData().getColumnName(i) + <br>": ";<br> rsJSON += rs.getString(i) + ", ";<br> } // end for<br> rsJSON += "},"; //end result set row<br> } //End while through result set<br> rsJSON += "]}" model={rs: <br>rsJSON}<br> con.close(); //clean up<br> // render a view with the data<br> library.view.render("test.ejs");<p> // Close the connection.<br> con.close();<p> }; // End on request function<br> };<br>});<p>Pooled Example:<p>response.setStatus(200);<br>response.setContentType("text/html");<br>writer = response.getWriter();<br>writer.println("<html><head><title>Phobos</title></head><body>");<br> <br>var conn = null;<br>var stmt = null;<br>var rset = null;<br>// custom module for pooled connection - start pool (normally done in <br>startup)<br>module.vfpDB.startConnectionPool();<p> writer.println("Pool Started<br>");<br> writer.println("Creating connection.<br>");<br> conn = <br>java.sql.DriverManager.getConnection("jdbc:apache:commons:dbcp:oConn");<br> writer.println("Creating statement.<br>");<br> var stmt = conn.createStatement();<br> writer.println("Executing statement.<br>");<br> rset = stmt.executeQuery('select * from some table);<br> writer.println("Results:<br>");<br> var numcols = rset.getMetaData().getColumnCount();<br> while (rset.next()) {<br> for(i=1;i<=numcols;i++) {<br> writer.println("<br>" + rset.getString(i));<br> }<br>}<br>writer.println("Closing Pool.<br>");<br>module.vfpDB.closeConnectionPool();<p>writer.println("</body></html>");<br>writer.flush();<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-566354715396386444?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com0tag:blogger.com,1999:blog-453476104242814492.post-19134888136189640882008-01-01T19:44:00.000-06:002008-01-01T20:33:21.444-06:00With the arrival of the holidays and some time off, I was able to spend some time coding on my personal Phobos project. The fourth quarter months were so busy, I was not able to devote much time to coding. I have developed a starter web site, but wanted to develop a simple CMS to make it easy to make additions to the site. I have integrated the open source FCK editor and laid most of the groundwork. I am in the process of working out the bugs now. Instead of posting code samples, I hope to post all of the source code and maybe even a project file. I am pursuing it as time permits.<br /><br />On another note, on a work related project, I have had to review a large amount of shopping cart software for selection for a new site. The languages covered were Java, PHP and .Net. One of the big requirements was the ability to get data in and out of the system easily in real time for integration into other business systems. After that, there was a need for a large amount of shopping features. Access to source code was also a must have feature whether it be open source or closed source. The system also needed to be somewhat economical for small business.<br /><br />The two main Java options seemed to be KonaKart and SoftSlate. The KonaKart integration looked promising and the shopping system had plenty of features, but while it is free, they do not release the source code for their server side application. SoftSlate is an economical package with access to source code, but they do not expose web services and from what information I could gather, you would need to write your own integration code for external connections.<br /><br />There were many php carts out there such as osCommerce, ZenCart and X-Cart. All of these are powerful, feature rich systems. Most of the integration features however consisted of importing data from a text file. While this is nice for total web based applications, it does not fare well interconnecting different business systems. Unfortunately, there wasn't much in the way of documentation as to how to get data in and out of these systems. It would be easy enough to write your own code, but on a complicated system, you wouldn't expect to write data directly to tables without having clear instructions on what data needs to go where. Many of the php carts say that they are working on data and layer abstractions.<br /><br />I reviewed a few dotnet systems and the one that seemed to shine was AspDotNetStorefront. It was reasonably priced, you have access to source code and external integration in real time is extensive. It is based on proprietary technology, but it does provide advanced features, integration, and source code.<br /><br />Out of the systems reviewed, it was interesting that depending on the language used, greatly affected the ability of others to work with a complicated system created by someone else. Most Java programmers abstract data access and other tasks. The object oriented nature of Java forces you to do this. The same principle would apply somewhat with dotnet. With PHP and Classic ASP, nothing is abstracted and the code is very free flowing. The nature of these languages make it quick to get stuff done, but as a system gets complicated, maintenance can become difficult. It also makes it much harder for someone who is not familiar with the system to come in and be productive because there isn't a built in blue print. Obviously there are exceptions to all rules because everything is still programmer dependent.<br /><br />How does this affect Phobos? JavaScript is a very free flowing language and you can get things done very quickly with it. However, the Phobos architecture lends itself to write blue printed code. I think you can have the best of both worlds with Phobos. Of course this can be done in PHP now that it is object oriented as well as other languages, but the only language still that runs in the browser natively is JavaScript. <br /><br />I think there is still room for a good open source shopping cart out there as well as simple CMS systems. The web is constantly changing and integration is becoming key. I believe Phobos fits the bill for small and large applications. Simplicity backed by the power of the Java infrastructure.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-1913488813618964088?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com0tag:blogger.com,1999:blog-453476104242814492.post-7169127829030364002007-11-06T08:38:00.000-06:002007-11-06T09:06:03.998-06:00Phobos and System AdminLooking to move to Java and open source platforms and being a system admin, I have been working on setting up a public facing open source server. Although Phobos is a small part of that, it is a task that has to be learned and done if Phobos and Java are going to be the back bone of your web site. I find Linux and Java application servers more secure and easier to tune for specific security tasks, but the software still has to be learned and mastered. Running a Linux internal server is quite a different task than running an external server. Securing a server from the operating system up through the application is a real task with today's Internet. I am currently using a headless Debian server and Sun Application Server. I would love to try Solaris as soon as they have drivers available for a wider variety of hardware. <br /><br />I am getting close to completion and hope to be running a beta site soon built entirely on Phobos. I like to see new technologies and I am excited about Phobos. My goal is to help build a larger community committed to Phobos with the site. When I see a web technology, I always like to see what the people recommending it are doing with it and if they are actually running it themselves. Sure, you can use many tools that may be more automated and built for you for running a web site or application, but if a foundational technology is going to become popular, ready made pieces must be built using it. Therefore, everything on the site will be built using Phobos and Java. <br /><br />I will be soliciting for volunteers to help and contribute code for pieces of the site as I can only devote so much time to the project. My goal will be to build a community driven site with many contributors of examples as well as code for the web site.<br /><br />Watch this blog for the release site which will be coming soon.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-716912782903036400?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com0tag:blogger.com,1999:blog-453476104242814492.post-63537642172511356822007-10-18T13:16:00.000-05:002007-10-18T13:33:55.388-05:00Phobos Data Access<p>Previously I had posted an example for setting up a database connection pool using Apache commons. I have rough drafted an application module and a sample script to use it. We still need logging and a few other things in the module, but it is a start. We could also develop module and properties for other information in the pool.<br /></p><p><br /></p><p>Here is the script to use the module.</p><br /><style type="text/css"><br /><!-- .syntax0 { color: #000000; } .syntax1 { background: #ffff00; color: #000000; font-style: italic; } .syntax2 { color: #ff8400; } .syntax3 { color: #6600cc; } .syntax4 { color: #cc6600; } .syntax5 { color: #ff0000; } .syntax6 { color: #9966ff; } .syntax7 { background: #ffffcc; color: #ff0066; } .syntax8 { color: #006699; font-weight: bold; } .syntax9 { color: #009966; font-weight: bold; } .syntax10 { color: #0099ff; font-weight: bold; } .syntax11 { color: #66ccff; font-weight: bold; } .syntax12 { color: #02b902; } .syntax13 { color: #ff00cc; } .syntax14 { color: #cc00cc; } .syntax15 { color: #9900cc; } .syntax16 { color: #6600cc; } .syntax17 { color: #0000ff; } .syntax18 { color: #000000; font-weight: bold; } .gutter { background: #dbdbdb; color: #000000; } .gutterH { background: #dbdbdb; color: #990066; } --><br /></style><br /><p></p><pre><br /><span class="syntax0"><span class="gutter"> 1:</span>response<span class="syntax18">.</span>setStatus(<span class="syntax5">200</span>);<br /><span class="gutter"> 2:</span>response<span class="syntax18">.</span>setContentType(<span class="syntax13">"</span><span class="syntax13">text/html</span><span class="syntax13">"</span>);<br /><span class="gutter"> 3:</span>writer <span class="syntax18">=</span> response<span class="syntax18">.</span>getWriter();<br /><span class="gutter"> 4:</span>writer<span class="syntax18">.</span>println(<span class="syntax13">"</span><span class="syntax13"><html><head><title>Phobos</title></head><body></span><span class="syntax13">"</span>);<br /><span class="gutterH"> 5:</span><br /><span class="gutter"> 6:</span>var conn <span class="syntax18">=</span> <span class="syntax10">null</span>;<br /><span class="gutter"> 7:</span>var stmt <span class="syntax18">=</span> <span class="syntax10">null</span>;<br /><span class="gutter"> 8:</span>var rset <span class="syntax18">=</span> <span class="syntax10">null</span>;<br /><span class="gutter"> 9:</span><span class="syntax8">if</span> (globals<span class="syntax18">.</span>oConnRunning) {<br /><span class="gutterH"> 10:</span> writer<span class="syntax18">.</span>println(<span class="syntax13">"</span><span class="syntax13">Pool</span><span class="syntax13"> </span><span class="syntax13">Running.<br></span><span class="syntax13">"</span>);<br /><span class="gutter"> 11:</span>}<br /><span class="gutter"> 12:</span><br /><span class="gutter"> 13:</span>writer<span class="syntax18">.</span>println(<span class="syntax13">"</span><span class="syntax13">Creating</span><span class="syntax13"> </span><span class="syntax13">connection.<br></span><span class="syntax13">"</span>);<br /><span class="gutter"> 14:</span>conn <span class="syntax18">=</span> java<span class="syntax18">.</span>sql<span class="syntax18">.</span>DriverManager<span class="syntax18">.</span>getConnection(<span class="syntax13">"</span><span class="syntax13">jdbc:apache:commons:dbcp:oConn</span><span class="syntax13">"</span>);<br /><span class="gutterH"> 15:</span>writer<span class="syntax18">.</span>println(<span class="syntax13">"</span><span class="syntax13">Creating</span><span class="syntax13"> </span><span class="syntax13">statement.<br></span><span class="syntax13">"</span>);<br /><span class="gutter"> 16:</span>var stmt <span class="syntax18">=</span> conn<span class="syntax18">.</span>createStatement();<br /><span class="gutter"> 17:</span>writer<span class="syntax18">.</span>println(<span class="syntax13">"</span><span class="syntax13">Executing</span><span class="syntax13"> </span><span class="syntax13">statement.<br></span><span class="syntax13">"</span>);<br /><span class="gutter"> 18:</span>rset <span class="syntax18">=</span> stmt<span class="syntax18">.</span>executeQuery(<span class="syntax1">'</span><span class="syntax1">Select</span><span class="syntax1"> </span><span class="syntax1">*</span><span class="syntax1"> </span><span class="syntax1">from</span><span class="syntax1"> </span><span class="syntax1">customer');</span><br /><span class="gutter"> 19:</span>writer<span class="syntax18">.</span>println(<span class="syntax13">"</span><span class="syntax13">Results:<br></span><span class="syntax13">"</span>);<br /><span class="gutterH"> 20:</span>var numcols <span class="syntax18">=</span> rset<span class="syntax18">.</span>getMetaData()<span class="syntax18">.</span>getColumnCount();<br /><span class="gutter"> 21:</span><span class="syntax8">while</span> (rset<span class="syntax18">.</span><span class="syntax8">next</span>()) {<br /><span class="gutter"> 22:</span> <span class="syntax8">for</span>(i<span class="syntax18">=</span><span class="syntax5">1</span>;i<span class="syntax18"><</span><span class="syntax18">=</span>numcols;i<span class="syntax18">+</span><span class="syntax18">+</span>) {<br /><span class="gutter"> 23:</span> writer<span class="syntax18">.</span>println(<span class="syntax13">"</span><span class="syntax13"><br></span><span class="syntax13">"</span> <span class="syntax18">+</span> rset<span class="syntax18">.</span>getString(i));<br /><span class="gutter"> 24:</span> }<br /><span class="gutterH"> 25:</span>}<br /><span class="gutter"> 26:</span><br /><span class="gutter"> 27:</span>writer<span class="syntax18">.</span>println(module<span class="syntax18">.</span>dbu<span class="syntax18">.</span>statsConnectionPool()<span class="syntax18">+</span><span class="syntax13">"</span><span class="syntax13"><br></span><span class="syntax13">"</span>);<br /><span class="gutter"> 28:</span>writer<span class="syntax18">.</span>println(<span class="syntax13">"</span><span class="syntax13">Closing</span><span class="syntax13"> </span><span class="syntax13">Pool.<br></span><span class="syntax13">"</span>);<br /><span class="gutter"> 29:</span>module<span class="syntax18">.</span>dbu<span class="syntax18">.</span>closeConnectionPool();<br /><span class="gutterH"> 30:</span><span class="syntax8">if</span> (globals<span class="syntax18">.</span>oConnRunning<span class="syntax18">=</span><span class="syntax18">=</span><span class="syntax10">false</span>) {<br /><span class="gutter"> 31:</span> writer<span class="syntax18">.</span>println(<span class="syntax13">"</span><span class="syntax13">Pool</span><span class="syntax13"> </span><span class="syntax13">Stopped.<br></span><span class="syntax13">"</span>);<br /><span class="gutter"> 32:</span>}<br /><span class="gutter"> 33:</span>writer<span class="syntax18">.</span>println(<span class="syntax13">"</span><span class="syntax13"></body></html></span><span class="syntax13">"</span>);<br /><span class="gutter"> 34:</span>writer<span class="syntax18">.</span>flush();<br /></span></pre><br /><br /><p>Here is a the module.</p><br /><pre><br /><span class="syntax0"><span class="gutter"> 1:</span>library<span class="syntax18">.</span>common<span class="syntax18">.</span><span class="syntax6">define(</span>module<span class="syntax18">,</span> <span class="syntax13">"</span><span class="syntax13">dbu</span><span class="syntax13">"</span><span class="syntax18">,</span> <span class="syntax6">function(</span><span class="syntax6">)</span> <span class="syntax18">{</span><br /><br /><span class="gutter"> 2:</span> <span class="syntax2">//</span><span class="syntax2"> </span><span class="syntax2">used</span><span class="syntax2"> </span><span class="syntax2">to</span><span class="syntax2"> </span><span class="syntax2">start</span><span class="syntax2"> </span><span class="syntax2">connection</span><span class="syntax2"> </span><span class="syntax2">pool</span><br /><span class="gutter"> 3:</span> <span class="syntax14">this</span><span class="syntax18">.</span>startConnectionPool <span class="syntax18">=</span> <span class="syntax6">function(</span><span class="syntax6">)</span> <span class="syntax18">{</span><br /><br /><span class="gutter"> 4:</span> <span class="syntax8">try</span> <span class="syntax18">{</span><br /><span class="gutterH"> 5:</span> java<span class="syntax18">.</span>lang<span class="syntax18">.</span><span class="syntax8">Class</span><span class="syntax18">.</span><span class="syntax6">forName(</span><span class="syntax13">"</span><span class="syntax13">org.apache.derby.jdbc.ClientDriver</span><span class="syntax13">"</span><span class="syntax6">)</span><span class="syntax18">;</span><br /><br /><span class="gutter"> 6:</span> <span class="syntax2">//</span><span class="syntax2"> </span><span class="syntax2">First,</span><span class="syntax2"> </span><span class="syntax2">we'll</span><span class="syntax2"> </span><span class="syntax2">need</span><span class="syntax2"> </span><span class="syntax2">a</span><span class="syntax2"> </span><span class="syntax2">ObjectPool</span><span class="syntax2"> </span><span class="syntax2">that</span><span class="syntax2"> </span><span class="syntax2">serves</span><span class="syntax2"> </span><span class="syntax2">as</span><span class="syntax2"> </span><span class="syntax2">the</span><span class="syntax2"> </span><span class="syntax2">actual</span><span class="syntax2"> </span><span class="syntax2">pool</span><span class="syntax2"> </span><span class="syntax2">of</span><span class="syntax2"> </span><span class="syntax2">connections.</span><br /><br /><span class="gutter"> 7:</span> <span class="syntax8">var</span> connectionPool <span class="syntax18">=</span> <span class="syntax8">new</span> Packages<span class="syntax18">.</span>org<span class="syntax18">.</span>apache<span class="syntax18">.</span>commons<span class="syntax18">.</span>pool<span class="syntax18">.</span>impl<span class="syntax18">.</span><span class="syntax6">GenericObjectPool(</span><span class="syntax6">)</span><span class="syntax18">;</span><br /><br /><span class="gutter"> 8:</span> <span class="syntax2">//</span><span class="syntax2"> </span><span class="syntax2">Set</span><span class="syntax2"> </span><span class="syntax2">up</span><span class="syntax2"> </span><span class="syntax2">our</span><span class="syntax2"> </span><span class="syntax2">connect</span><span class="syntax2"> </span><span class="syntax2">string</span><span class="syntax2"> </span><span class="syntax2">for</span><span class="syntax2"> </span><span class="syntax2">our</span><span class="syntax2"> </span><span class="syntax2">database</span><br /><br /><span class="gutter"> 9:</span> <span class="syntax8">var</span> connectURI <span class="syntax18">=</span> <span class="syntax13">'</span><span class="syntax13">jdbc:derby://localhost:1527/sample;user=app;password=app</span><span class="syntax13">'</span><span class="syntax18">;</span><br /><span class="gutterH"> 10:</span> <span class="syntax2">//</span><span class="syntax2"> </span><span class="syntax2">Next,</span><span class="syntax2"> </span><span class="syntax2">we'll</span><span class="syntax2"> </span><span class="syntax2">create</span><span class="syntax2"> </span><span class="syntax2">a</span><span class="syntax2"> </span><span class="syntax2">ConnectionFactory</span><span class="syntax2"> </span><span class="syntax2">that</span><span class="syntax2"> </span><span class="syntax2">the</span><span class="syntax2"> </span><span class="syntax2">pool</span><span class="syntax2"> </span><span class="syntax2">will</span><span class="syntax2"> </span><span class="syntax2">use</span><span class="syntax2"> </span><span class="syntax2">to</span><span class="syntax2"> </span><span class="syntax2">create</span><span class="syntax2"> </span><span class="syntax2">Connections.</span><br /><br /><span class="gutter"> 11:</span> <span class="syntax2">//</span><span class="syntax2"> </span><span class="syntax2">We'll</span><span class="syntax2"> </span><span class="syntax2">use</span><span class="syntax2"> </span><span class="syntax2">the</span><span class="syntax2"> </span><span class="syntax2">DriverManagerConnectionFactory</span><br /><span class="gutter"> 12:</span> connectionFactory <span class="syntax18">=</span> <span class="syntax8">new</span> Packages<span class="syntax18">.</span>org<span class="syntax18">.</span>apache<span class="syntax18">.</span>commons<span class="syntax18">.</span>dbcp<span class="syntax18">.</span><span class="syntax6">DriverManagerConnectionFactory(</span>connectURI<span class="syntax18">,</span><span class="syntax14">null</span><span class="syntax6">)</span><span class="syntax18">;</span><br /><br /><span class="gutter"> 13:</span> <span class="syntax2">//</span><span class="syntax2"> </span><span class="syntax2">Now</span><span class="syntax2"> </span><span class="syntax2">we'll</span><span class="syntax2"> </span><span class="syntax2">create</span><span class="syntax2"> </span><span class="syntax2">the</span><span class="syntax2"> </span><span class="syntax2">PoolableConnectionFactory,</span><span class="syntax2"> </span><span class="syntax2">which</span><span class="syntax2"> </span><span class="syntax2">wraps</span><br /><br /><span class="gutter"> 14:</span> <span class="syntax2">//</span><span class="syntax2"> </span><span class="syntax2">the</span><span class="syntax2"> </span><span class="syntax2">"real"</span><span class="syntax2"> </span><span class="syntax2">Connections</span><span class="syntax2"> </span><span class="syntax2">created</span><span class="syntax2"> </span><span class="syntax2">by</span><span class="syntax2"> </span><span class="syntax2">the</span><span class="syntax2"> </span><span class="syntax2">ConnectionFactory</span><span class="syntax2"> </span><span class="syntax2">with</span><br /><br /><span class="gutterH"> 15:</span> <span class="syntax2">//</span><span class="syntax2"> </span><span class="syntax2">the</span><span class="syntax2"> </span><span class="syntax2">classes</span><span class="syntax2"> </span><span class="syntax2">that</span><span class="syntax2"> </span><span class="syntax2">implement</span><span class="syntax2"> </span><span class="syntax2">the</span><span class="syntax2"> </span><span class="syntax2">pooling</span><span class="syntax2"> </span><span class="syntax2">functionality.</span><br /><br /><span class="gutter"> 16:</span> poolableConnectionFactory <span class="syntax18">=</span> <span class="syntax8">new</span> Packages<span class="syntax18">.</span>org<span class="syntax18">.</span>apache<span class="syntax18">.</span>commons<span class="syntax18">.</span>dbcp<span class="syntax18">.</span><span class="syntax6">PoolableConnectionFactory(</span>connectionFactory<span class="syntax18">,</span>connectionPool<span class="syntax18">,</span><span class="syntax14">null</span><span class="syntax18">,</span><span class="syntax14">null</span><span class="syntax18">,</span><span class="syntax14">false</span><span class="syntax18">,</span><span class="syntax14">true</span><span class="syntax6">)</span><span class="syntax18">;</span><br /><br /><span class="gutter"> 17:</span> <span class="syntax2">//</span><span class="syntax2"> </span><span class="syntax2">Finally,</span><span class="syntax2"> </span><span class="syntax2">we</span><span class="syntax2"> </span><span class="syntax2">create</span><span class="syntax2"> </span><span class="syntax2">the</span><span class="syntax2"> </span><span class="syntax2">PoolingDriver</span><span class="syntax2"> </span><span class="syntax2">itself</span><br /><br /><span class="gutter"> 18:</span> java<span class="syntax18">.</span>lang<span class="syntax18">.</span><span class="syntax8">Class</span><span class="syntax18">.</span><span class="syntax6">forName(</span><span class="syntax13">"</span><span class="syntax13">org.apache.commons.dbcp.PoolingDriver</span><span class="syntax13">"</span><span class="syntax6">)</span><span class="syntax18">;</span><br /><span class="gutter"> 19:</span> <span class="syntax2">//</span><span class="syntax2"> </span><span class="syntax2">...and</span><span class="syntax2"> </span><span class="syntax2">register</span><span class="syntax2"> </span><span class="syntax2">our</span><span class="syntax2"> </span><span class="syntax2">pool</span><span class="syntax2"> </span><span class="syntax2">with</span><span class="syntax2"> </span><span class="syntax2">it.</span><br /><br /><span class="gutterH"> 20:</span> <span class="syntax8">var</span> driver <span class="syntax18">=</span> java<span class="syntax18">.</span>sql<span class="syntax18">.</span>DriverManager<span class="syntax18">.</span><span class="syntax6">getDriver(</span><span class="syntax13">"</span><span class="syntax13">jdbc:apache:commons:dbcp:</span><span class="syntax13">"</span><span class="syntax6">)</span><span class="syntax18">;</span><br /><br /><span class="gutter"> 21:</span> <span class="syntax2">//</span><span class="syntax2"> </span><span class="syntax2">Now</span><span class="syntax2"> </span><span class="syntax2">we</span><span class="syntax2"> </span><span class="syntax2">can</span><span class="syntax2"> </span><span class="syntax2">just</span><span class="syntax2"> </span><span class="syntax2">use</span><span class="syntax2"> </span><span class="syntax2">the</span><span class="syntax2"> </span><span class="syntax2">connect</span><span class="syntax2"> </span><span class="syntax2">string</span><span class="syntax2"> </span><span class="syntax2">"jdbc:apache:commons:dbcp:example"</span><br /><br /><span class="gutter"> 22:</span> <span class="syntax2">//</span><span class="syntax2"> </span><span class="syntax2">to</span><span class="syntax2"> </span><span class="syntax2">access</span><span class="syntax2"> </span><span class="syntax2">our</span><span class="syntax2"> </span><span class="syntax2">pool</span><span class="syntax2"> </span><span class="syntax2">of</span><span class="syntax2"> </span><span class="syntax2">Connections.</span><br /><br /><span class="gutter"> 23:</span> driver<span class="syntax18">.</span><span class="syntax6">registerPool(</span><span class="syntax13">"</span><span class="syntax13">oConn</span><span class="syntax13">"</span><span class="syntax18">,</span>connectionPool<span class="syntax6">)</span><span class="syntax18">;</span><br /><span class="gutter"> 24:</span> globals<span class="syntax18">.</span>oConnRunning <span class="syntax18">=</span> <span class="syntax14">true</span><span class="syntax18">;</span><br /><br /><span class="gutterH"> 25:</span> <span class="syntax8">return</span> <span class="syntax14">true</span><span class="syntax18">;</span><br /><span class="gutter"> 26:</span> <span class="syntax18">}</span><br /><span class="gutter"> 27:</span> <span class="syntax6">catch(</span>exception<span class="syntax6">)</span> <span class="syntax18">{</span><br /><br /><span class="gutter"> 28:</span> globals<span class="syntax18">.</span>oConnRunning <span class="syntax18">=</span> <span class="syntax14">false</span><span class="syntax18">;</span><br /><span class="gutter"> 29:</span> <span class="syntax8">return</span> <span class="syntax14">false</span><span class="syntax18">;</span><br /><br /><span class="gutterH"> 30:</span> <span class="syntax18">}</span> <br /><span class="gutter"> 31:</span> <span class="syntax18">}</span><span class="syntax2">//</span><span class="syntax2"> </span><span class="syntax2">startConnectionPool</span><br /><span class="gutter"> 32:</span><br /><span class="gutter"> 33:</span> <span class="syntax2">//</span><span class="syntax2"> </span><span class="syntax2">Close</span><span class="syntax2"> </span><span class="syntax2">the</span><span class="syntax2"> </span><span class="syntax2">connection</span><span class="syntax2"> </span><span class="syntax2">pool</span><br /><br /><span class="gutter"> 34:</span> <span class="syntax14">this</span><span class="syntax18">.</span>closeConnectionPool <span class="syntax18">=</span> <span class="syntax6">function(</span><span class="syntax6">)</span> <span class="syntax18">{</span><br /><span class="gutterH"> 35:</span> <span class="syntax8">try</span> <span class="syntax18">{</span><br /><br /><span class="gutter"> 36:</span> <span class="syntax8">var</span> driver <span class="syntax18">=</span> java<span class="syntax18">.</span>sql<span class="syntax18">.</span>DriverManager<span class="syntax18">.</span><span class="syntax6">getDriver(</span><span class="syntax13">"</span><span class="syntax13">jdbc:apache:commons:dbcp:</span><span class="syntax13">"</span><span class="syntax6">)</span><span class="syntax18">;</span><br /><br /><span class="gutter"> 37:</span> driver<span class="syntax18">.</span><span class="syntax6">closePool(</span><span class="syntax13">"</span><span class="syntax13">oConn</span><span class="syntax13">"</span><span class="syntax6">)</span><span class="syntax18">;</span><br /><span class="gutter"> 38:</span> globals<span class="syntax18">.</span>oConnRunning <span class="syntax18">=</span> <span class="syntax14">false</span><span class="syntax18">;</span><br /><br /><span class="gutter"> 39:</span> <span class="syntax8">return</span> <span class="syntax14">true</span><span class="syntax18">;</span><br /><span class="gutterH"> 40:</span> <span class="syntax18">}</span><br /><span class="gutter"> 41:</span> <span class="syntax6">catch(</span>exception<span class="syntax6">)</span> <span class="syntax18">{</span><br /><br /><span class="gutter"> 42:</span> <span class="syntax8">return</span> <span class="syntax14">false</span><span class="syntax18">;</span><br /><span class="gutter"> 43:</span> <span class="syntax18">}</span><br /><span class="gutter"> 44:</span> <span class="syntax18">}</span><span class="syntax2">//</span><span class="syntax2"> </span><span class="syntax2">Close</span><span class="syntax2"> </span><span class="syntax2">connection</span><span class="syntax2"> </span><span class="syntax2">pool</span><br /><br /><span class="gutterH"> 45:</span><br /><span class="gutter"> 46:</span> <span class="syntax2">//</span><span class="syntax2"> </span><span class="syntax2">Connection</span><span class="syntax2"> </span><span class="syntax2">pool</span><span class="syntax2"> </span><span class="syntax2">stats</span><br /><span class="gutter"> 47:</span> <span class="syntax2">//</span><span class="syntax2">Returns</span><span class="syntax2"> </span><span class="syntax2">number</span><span class="syntax2"> </span><span class="syntax2">active</span><span class="syntax2"> </span><span class="syntax2">and</span><span class="syntax2"> </span><span class="syntax2">idle</span><span class="syntax2"> </span><span class="syntax2">in</span><span class="syntax2"> </span><span class="syntax2">format</span><span class="syntax2"> </span><span class="syntax2">active,idle</span><span class="syntax2"> </span><span class="syntax2">eg</span><span class="syntax2"> </span><span class="syntax2">3,10</span><br /><br /><span class="gutter"> 48:</span> <span class="syntax14">this</span><span class="syntax18">.</span>statsConnectionPool <span class="syntax18">=</span> <span class="syntax6">function(</span><span class="syntax6">)</span> <span class="syntax18">{</span><br /><span class="gutter"> 49:</span> <span class="syntax8">var</span> driver <span class="syntax18">=</span> java<span class="syntax18">.</span>sql<span class="syntax18">.</span>DriverManager<span class="syntax18">.</span><span class="syntax6">getDriver(</span><span class="syntax13">"</span><span class="syntax13">jdbc:apache:commons:dbcp:</span><span class="syntax13">"</span><span class="syntax6">)</span><span class="syntax18">;</span><br /><br /><span class="gutterH"> 50:</span> connectionPool <span class="syntax18">=</span> driver<span class="syntax18">.</span><span class="syntax6">getConnectionPool(</span><span class="syntax13">"</span><span class="syntax13">oConn</span><span class="syntax13">"</span><span class="syntax6">)</span><span class="syntax18">;</span><br /><span class="gutter"> 51:</span> <span class="syntax8">var</span> stats <span class="syntax18">=</span> connectionPool<span class="syntax18">.</span><span class="syntax6">getNumActive(</span><span class="syntax6">)</span> <span class="syntax18">+</span> <span class="syntax13">"</span><span class="syntax13">,</span><span class="syntax13">"</span> <span class="syntax18">+</span> connectionPool<span class="syntax18">.</span><span class="syntax6">getNumIdle(</span><span class="syntax6">)</span><span class="syntax18">;</span><br /><br /><span class="gutter"> 52:</span> <span class="syntax8">return</span> stats<span class="syntax18">;</span><br /><span class="gutter"> 53:</span> <span class="syntax18">}</span><span class="syntax2">//</span><span class="syntax2">stats</span><span class="syntax2"> </span><span class="syntax2">connection</span><span class="syntax2"> </span><span class="syntax2">Pool</span><br /><br /><span class="gutter"> 54:</span><span class="syntax18">}</span><span class="syntax6">)</span><span class="syntax18">;</span><br /><span class="gutterH"> 55:</span><br /></span></pre><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-6353764217251135682?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com0tag:blogger.com,1999:blog-453476104242814492.post-22812975294952070992007-10-04T09:17:00.000-05:002007-10-04T09:29:43.402-05:00Phobos - Database - Apache CommonsI have been playing with data access from Phobos for some time now and was looking for a data solution with the following objectives in mind.<br /><br />1) Data Pooling and Caching should be done within Phobos. This will make a Phobos application application server agnostic. There would be no extra application server configuration.<br /><br />2) It should be fairly easy to use multiple databases from different vendors or projects.<br /><br />3) You should be able to control the process all the way down to the connection from Phobos, but also be able to abstract access so pieces of the application do not need to know about the connection.<br /><br />4) The solution should be simple. The end goal is for a basic web application. For large, enterprise applications, a custom application server specific solution can be achieved easily by an IT department.<br /><br />After some research, I decided to try the Apache Commons components for database caching. I used a Java connection pooling example and converted it to a Phobos script to do essentially the same thing using the same Java objects. I have tested it and have it working with Derby and the app database included with Netbeans 6.0.<br /><br />The next step would be to put the data access code in a Phobos module to abstract the database access and include some utility methods as well as error trapping.<br /><br />I also would like to mention how easy this process was. I am not a Java programmer. I have read some books and written some basic programs, but would not consider myself fluent in Java by any means. However, using Javascript and Phobos, you can utilize the power of these Java objects rather easily.<br /><br />*******************************************************************<br /><br />Here is the Phobos script:<br /><br /><span style="color: rgb(255, 0, 0);">// This will set up our writer.<br />// We could do this with a dynamic script or view as well</span><br />response.setStatus(200);<br />response.setContentType("text/html");<br />writer = response.getWriter();<br />writer.println("<html><head><title>Hello</title></head><body>")<br /><br /><span style="color: rgb(255, 0, 0);">// Set up our connection by specifying the driver</span><br />java.lang.Class.forName("org.apache.derby.jdbc.ClientDriver");<br /><br /><span style="color: rgb(255, 0, 0);">// First, we'll need a ObjectPool that serves as the actual pool of connections.</span><br />var connectionPool = new Packages.org.apache.commons.pool.impl.GenericObjectPool();<br /><br /><span style="color: rgb(255, 0, 0);">// Set up our connect string for our database</span><br />var connectURI = 'jdbc:derby://localhost:1527/sample;user=app;password=app';<br /><br /><span style="color: rgb(255, 0, 0);">// Next, we'll create a ConnectionFactory that the pool will use to create Connections.<br />// We'll use the DriverManagerConnectionFactory</span><br />connectionFactory = new Packages.org.apache.commons.dbcp.DriverManagerConnectionFactory(connectURI,null);<br /><br /><span style="color: rgb(255, 0, 0);">// Now we'll create the PoolableConnectionFactory, which wraps<br />// the "real" Connections created by the ConnectionFactory with<br />// the classes that implement the pooling functionality.</span><br />poolableConnectionFactory = new Packages.org.apache.commons.dbcp.PoolableConnectionFactory(connectionFactory,connectionPool,null,null,false,true);<br /><br /><span style="color: rgb(255, 0, 0);">// Finally, we create the PoolingDriver itself</span><br />java.lang.Class.forName("org.apache.commons.dbcp.PoolingDriver");<br /><br /><span style="color: rgb(255, 0, 0);">// ...and register our pool with it.</span><br />driver = java.sql.DriverManager.getDriver("jdbc:apache:commons:dbcp:");<br /><br /><span style="color: rgb(255, 0, 0);">// Now we can just use the connect string "jdbc:apache:commons:dbcp:example"<br />// to access our pool of Connections.</span><br />driver.registerPool("example",connectionPool);<br /><span style="color: rgb(255, 0, 0);">// This is the end of the setup code<br /></span><br /><span style="color: rgb(255, 0, 0);">// Now, we can use JDBC as we normally would.<br />// Using the connect string<br />// jdbc:apache:commons:dbcp:example<br />// The general form being:<br />// jdbc:apache:commons:dbcp:<name-of-pool></span><br />var conn = null;<br />var stmt = null;<br />var rset = null;<br /><br />writer.println("Creating connection.<br>");<br />conn = java.sql.DriverManager.getConnection("jdbc:apache:commons:dbcp:example");<br />writer.println("Creating statement.<br>");<br />var stmt = conn.createStatement();<br />writer.println("Executing statement.<br>");<br />rset = stmt.executeQuery('Select * from customer');<br />writer.println("Results:<br>");<br />var numcols = rset.getMetaData().getColumnCount();<br />while (rset.next()) {<br /> for(i=1;i<=numcols;i++) {<br /> writer.println("<br>" + rset.getString(i));<br /> }<br />}<br />writer.println("</body></html>");<br />writer.flush();<br /><br />*********************************************************************************<br /><br />Here is the Apache Commons example:<br /><br />/*<br /> * Copyright 1999-2004 The Apache Software Foundation.<br /> * <br /> * Licensed under the Apache License, Version 2.0 (the "License");<br /> * you may not use this file except in compliance with the License.<br /> * You may obtain a copy of the License at<br /> * <br /> * http://www.apache.org/licenses/LICENSE-2.0<br /> * <br /> * Unless required by applicable law or agreed to in writing, software<br /> * distributed under the License is distributed on an "AS IS" BASIS,<br /> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<br /> * See the License for the specific language governing permissions and<br /> * limitations under the License.<br /> */<br /><br />import java.sql.DriverManager;<br />import java.sql.Connection;<br />import java.sql.Statement;<br />import java.sql.ResultSet;<br />import java.sql.SQLException;<br /><br />//<br />// Here are the dbcp-specific classes.<br />// Note that they are only used in the setupDriver<br />// method. In normal use, your classes interact<br />// only with the standard JDBC API<br />//<br />import org.apache.commons.pool.ObjectPool;<br />import org.apache.commons.pool.impl.GenericObjectPool;<br />import org.apache.commons.dbcp.ConnectionFactory;<br />import org.apache.commons.dbcp.PoolingDriver;<br />import org.apache.commons.dbcp.PoolableConnectionFactory;<br />import org.apache.commons.dbcp.DriverManagerConnectionFactory;<br /><br />//<br />// Here's a simple example of how to use the PoolingDriver.<br />// In this example, we'll construct the PoolingDriver manually,<br />// just to show how the pieces fit together, but you could also<br />// configure it using an external conifguration file in<br />// JOCL format (and eventually Digester).<br />//<br /><br />//<br />// To compile this example, you'll want:<br />// * commons-pool.jar<br />// * commons-dbcp.jar<br />// in your classpath.<br />//<br />// To run this example, you'll want:<br />// * commons-collections.jar<br />// * commons-pool.jar<br />// * commons-dbcp.jar<br />// * the classes for your (underlying) JDBC driver<br />// in your classpath.<br />//<br />// Invoke the class using two arguments:<br />// * the connect string for your underlying JDBC driver<br />// * the query you'd like to execute<br />// You'll also want to ensure your underlying JDBC driver<br />// is registered. You can use the "jdbc.drivers"<br />// property to do this.<br />//<br />// For example:<br />// java -Djdbc.drivers=oracle.jdbc.driver.OracleDriver \<br />// -classpath commons-collections.jar:commons-pool.jar:commons-dbcp.jar:oracle-jdbc.jar:. \<br />// ManualPoolingDriverExample<br />// "jdbc:oracle:thin:scott/tiger@myhost:1521:mysid"<br />// "SELECT * FROM DUAL"<br />//<br />public class ManualPoolingDriverExample {<br /><br /> public static void main(String[] args) {<br /> //<br /> // First we load the underlying JDBC driver.<br /> // You need this if you don't use the jdbc.drivers<br /> // system property.<br /> //<br /> System.out.println("Loading underlying JDBC driver.");<br /> try {<br /> Class.forName("oracle.jdbc.driver.OracleDriver");<br /> } catch (ClassNotFoundException e) {<br /> e.printStackTrace();<br /> }<br /> System.out.println("Done.");<br /><br /> //<br /> // Then we set up and register the PoolingDriver.<br /> // Normally this would be handled auto-magically by<br /> // an external configuration, but in this example we'll<br /> // do it manually.<br /> //<br /> System.out.println("Setting up driver.");<br /> try {<br /> setupDriver(args[0]);<br /> } catch (Exception e) {<br /> e.printStackTrace();<br /> }<br /> System.out.println("Done.");<br /><br /> //<br /> // Now, we can use JDBC as we normally would.<br /> // Using the connect string<br /> // jdbc:apache:commons:dbcp:example<br /> // The general form being:<br /> // jdbc:apache:commons:dbcp:<name-of-pool><br /> //<br /><br /> Connection conn = null;<br /> Statement stmt = null;<br /> ResultSet rset = null;<br /><br /> try {<br /> System.out.println("Creating connection.");<br /> conn = DriverManager.getConnection("jdbc:apache:commons:dbcp:example");<br /> System.out.println("Creating statement.");<br /> stmt = conn.createStatement();<br /> System.out.println("Executing statement.");<br /> rset = stmt.executeQuery(args[1]);<br /> System.out.println("Results:");<br /> int numcols = rset.getMetaData().getColumnCount();<br /> while(rset.next()) {<br /> for(int i=1;i<=numcols;i++) {<br /> System.out.print("\t" + rset.getString(i));<br /> }<br /> System.out.println("");<br /> }<br /> } catch(SQLException e) {<br /> e.printStackTrace();<br /> } finally {<br /> try { rset.close(); } catch(Exception e) { }<br /> try { stmt.close(); } catch(Exception e) { }<br /> try { conn.close(); } catch(Exception e) { }<br /> }<br /><br /> // Display some pool statistics<br /> try {<br /> printDriverStats();<br /> } catch (Exception e) {<br /> e.printStackTrace();<br /> }<br /><br /> // closes the pool<br /> try {<br /> shutdownDriver();<br /> } catch (Exception e) {<br /> e.printStackTrace();<br /> }<br /> }<br /><br /> public static void setupDriver(String connectURI) throws Exception {<br /> //<br /> // First, we'll need a ObjectPool that serves as the<br /> // actual pool of connections.<br /> //<br /> // We'll use a GenericObjectPool instance, although<br /> // any ObjectPool implementation will suffice.<br /> //<br /> ObjectPool connectionPool = new GenericObjectPool(null);<br /><br /> //<br /> // Next, we'll create a ConnectionFactory that the<br /> // pool will use to create Connections.<br /> // We'll use the DriverManagerConnectionFactory,<br /> // using the connect string passed in the command line<br /> // arguments.<br /> //<br /> ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(connectURI,null);<br /><br /> //<br /> // Now we'll create the PoolableConnectionFactory, which wraps<br /> // the "real" Connections created by the ConnectionFactory with<br /> // the classes that implement the pooling functionality.<br /> //<br /> PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory,connectionPool,null,null,false,true);<br /><br /> //<br /> // Finally, we create the PoolingDriver itself...<br /> //<br /> Class.forName("org.apache.commons.dbcp.PoolingDriver");<br /> PoolingDriver driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");<br /><br /> //<br /> // ...and register our pool with it.<br /> //<br /> driver.registerPool("example",connectionPool);<br /><br /> //<br /> // Now we can just use the connect string "jdbc:apache:commons:dbcp:example"<br /> // to access our pool of Connections.<br /> //<br /> }<br /><br /> public static void printDriverStats() throws Exception {<br /> PoolingDriver driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");<br /> ObjectPool connectionPool = driver.getConnectionPool("example");<br /> <br /> System.out.println("NumActive: " + connectionPool.getNumActive());<br /> System.out.println("NumIdle: " + connectionPool.getNumIdle());<br /> }<br /><br /> public static void shutdownDriver() throws Exception {<br /> PoolingDriver driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");<br /> driver.closePool("example");<br /> }<br />}<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-2281297529495207099?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com3tag:blogger.com,1999:blog-453476104242814492.post-79898395940892722892007-09-11T08:35:00.000-05:002007-09-11T08:55:20.518-05:00Current Events with PhobosRecently my day job has been extremely busy and therefore I have not had much time to post or work on my favorite projects. I have been working on doing a test run of setting up a system from scratch, a Java application server with Phobos. My main problems have not been with Phobos, but with system details.<br /><br />Setting up a Windows system was quite easy. Once the basic install was done, I installed Glassfish and deployed my shell Phobos application. No hitches there. I then set up a Centos 5 system and had some problems. Glassfish installed fine, but I could not get it to bind to the ports it needed. I disabled ipv6, the firewall etc, but still could not get it to go. I then tried Resin and had the same issue. When I tried running Jetty, it started up and ran just fine. After setting up a context in Jetty, I was able to deploy a Phobos app with no problem.<br /><br />I also set up a new laptop for work. It came with Vista preloaded. Since I am looking to try using all open source products, I tried loading Centos 5, but it was missing the video driver for this particular laptop. I then tried loading Linux Mint, which is based on Ubuntu, using the live CD. It loaded up so I partitioned the hard drive using QT Parted, and installed Linux on half of the hard drive so that I have a dual boot system. I loaded Netbeans from the software repository, but could not get it to start until I also loaded the Java 6 JDK. I guess the JRE is installed by default. I also installed my favorite all around editor from jedit.org. I have been using that for almost eight years now.<br /><br />I have been very happy with the Linux Mint distro so far. I hope to spend more time posting and working with Phobos in the next few months. I hope to see the beta of Netbeans 6 soon.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-7989839594089272289?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com0tag:blogger.com,1999:blog-453476104242814492.post-73986331259825043042007-08-03T08:50:00.000-05:002007-08-03T09:02:56.035-05:00Connecting to MSSQL with in Phobos<pre>Here is an example of connecting to MSSQL server directly using jdbc<br />from inside Phobos. This post shows how to make a connection only. You would <br />use this for test purposes. A production application would need a pooled<br />connection for performance. That will be posted in the future.<br /><br />*******************************************************************<br />// This will set up our writer.<br />// We could do this with a dynamic script or view as well<br />response.setStatus(200);<br />response.setContentType("text/html");<br />writer = response.getWriter();<br />// Set up our connection by specifying the driver<br />java.lang.Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");<br />var user = "user";<br />var pass = "pass";<br />var strconn =<br />"jdbc:sqlserver://server:port;databaseName=database;selectMethod=cursor;"<br />var con = new java.sql.DriverManager.getConnection(strconn,user,pass);<br />writer.println("strconn");<br />if (con!=null) {<br /> writer.println("Connection Successful");<br /> }<br />// Close the connection.<br />con.close();<br />writer.flush();<br /></pre><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-7398633125982504304?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com0tag:blogger.com,1999:blog-453476104242814492.post-42016488649875525372007-06-26T15:08:00.000-05:002007-06-26T15:14:55.039-05:00Phobos vs RailsSummer time is very busy with outdoor activities, family vacations, and spending time enjoying the great outdoors. It is refreshing to step back and then come back to networks and computer systems with a little different perspective on problems and solutions.<br /><br />I have been working on a test project with MSSQL and Phobos. I am using the MS JDBC driver, JPA and Phobos JPA generator. I have to compliment the Phobos team on the ease of use of the Phobos platform and focus on productivity of the developer. I see a lot of buzz about Ruby and Rails. When comparing Rails and Phobos so far, it seems that Phobos has just as much, if not more productivity with a greater simplicity.<br /><br />An example of hooking up a page to a database would be to create your tables in your database, Create a project in Netbeans and run the JPA wizard, compile and build the JPA project. Add the JPA class to your Phobos project, and run the JPA generator Phobos provides. You now have a basic interface and all the infrastructure code for reading, updating, and deleting records. You can now focus on the presentation area of your web project instead of spending time writing infrastructure code.<br /><br />While the Phobos team is still rounding out the platform, the simplicity and usability already really shines. With web developers using client side javascript, server side javascript is a natural choice for the server side as well.<br /><br />Be sure to check out the JPA wizard on the Phobos web site at <a href="https://phobos.dev.java.net/tutorials/jpagenerator/index.html">https://phobos.dev.java.net/tutorials/jpagenerator/index.html</a><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-4201648864987552537?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com0tag:blogger.com,1999:blog-453476104242814492.post-36592283742221909972007-05-29T21:51:00.000-05:002007-05-29T21:54:36.211-05:00Ease of Data AccessSummer is here, and when you live as far north as I live, that means you get out and enjoy the great outdoors every chance you get. I devote much more time to learning new technology and programming during the winter months. That being said, I will be devoting some hours to learning Sun's web platform this summer. Phobos and Jmaki in particular. So far I have found Phobos and Jmaki very easy to work with. I find it extremely easy to use Java objects as well. I am looking forward to the final release of Netbeans 6. <br /><br />There are a few issues that I think would help Phobos along. The first being that a simple data pipe is needed. Every user has data. Every simple website has data. In order for someone to find the whole platform easy to work with, there needs to be a simple data pipe. JPA is the new Java way of working with data. I agree that it is powerful and fast. However, there needs to be a simple pipe as well. Take the following scenario, someone has a database and they want to try Phobos out. If they had a simple data object that they could set a few properties, issue an sql statement, and get a data object back which they could then access to generate a presentation page, they would be successful getting there data and on to using Phobos to design an application. Now lets just say that they have trouble getting at their data, or something does not work right. Now they really have nothing to work with. They are now more likely to become frustrated and give up working with this new technology. <br /><br />Now consider another scenario. The beginner user programs a simple data access page and now deploys it as a web app. However, because now it is running in the application environment, a data pool has to be configured to access your data. Now the beginner user is frustrated and stops using this new technology because they cannot figure out how to make the web app work on the application server. I know it is impossible to make a default pipe on every application server, but it would be help to have something be standard on at least one like Glassfish. There could always be a simple pipe out of the box, and then if you wanted more performance, you could complete the steps necessary to achieve that performance by using pools and/or JPA. <br /><br />These all seem like minor issues to the average Java programmer, but for the beginner doing it for the first time, these can be huge issues. The JSF IDE builder in Netbeans is really RAD, but JSF programming is quite complex and far below scripting. The Phobos engine excels in simplicity, but a few added pieces of tooling would really make it fly. Data access just needs to work!<br /><br />The devoted Visual Foxpro community on the Microsoft side was developed because of easy data access.<br /><br />Phobos currently has a simple database library and also a JPA generator. These are pretty good, but I it still needs to be easier. The database library needs to be documented with some simple examples. The JPA generator is nice, but requires several steps. The Phobos team is doing a good job. I am sure better tooling is coming. Stay tuned!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-3659228374222190997?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com0tag:blogger.com,1999:blog-453476104242814492.post-70286118785718903912007-05-11T22:01:00.000-05:002007-05-11T22:05:42.483-05:00Java One, Phobos, JavaFXI have been watching with interest what has been happening at Java One this year via the web. To be honest, I have never really paid attention to it at all except to see a random news story here or there. Since I have begun using Phobos and looking for ways to move business applications to the Java platform, I have been following Java much more closely. My main area of interest was to see what the Phobos team was presenting and how Phobos fits into the big Java picture. The next thing which jumped out and I found exciting was the JavaFX announcement. I saw F3/JavaFX several months ago, but really have not paid attention to it, but was pleasantly surprised by how far it has come and how it is being developed. It is exciting to see Sun putting effort into making simple, easy to use tools. In my book, this is finally an effort in the right direction to draw new, non-Java programmers into the Java platform. This is what needs to happen in order for Java to dominate and neutralize the operating system monopoly. <br /><br />It was sad to see the reaction Java developers and Java bloggers being critical of Sun's efforts and JavaFX. With Phobos and JavaFX built on top of Java, Java is not going to go away. Java programmers will still be able to code in Java. What is the problem with building a simple declarative language with easy binding? What is wrong with designing an interpreted language running on the Java stack? What is wrong with bringing the level of complexity to write on top of the Java stack to a very simple proposition? It seems many Java programmers are their own enemy. It is time for Java developers to have some enthusiasm about the Java platform striving to encompass and invite, in whatever ways necessary, those developers who are using other languages. That does not mean forcing them to learn Java. That means creating a migration path that is feasible and comfortable, and giving them the tools to do so. Sun is finally doing it, and it is about time that Java developers and Java bloggers get in the game and support Sun's effort. It is in every Java developers best interest to do so.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-7028611878571890391?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com1tag:blogger.com,1999:blog-453476104242814492.post-80730895591535703462007-05-03T22:23:00.000-05:002007-05-03T22:38:50.710-05:00Phobos And Data AccessThe last few weeks I have been working on some Phobos applications internal to our company and trying to work out the best way to access databases for both data display uses and form usage requiring persistence. The Phobos team has produced a generator which produces all the tiers of code which you can then modify once you have run the generator. The only stipulation is that you have run the JPA wizard on your database and have produced the needed JPA jar by using Netbeans. The JPA Jar is easily produced with the Netbeans wizard if you have a new database and there doesn't happen to be any wrinkles. I accomplished the whole task for a sample app in about thirty minutes. Considering I started with nothing and when I was done, I had a database with tables, a persistence unit, application server code, and a rough web interface, I would say that the process is pretty impressive! The Netbeans and Phobos team have a done a great job.<br /><br />However, there is more to life than roses. It is not so easy when working with legacy data. For instance, it is not uncommon to have data in at least a couple of different databases. If we need to pull data from MSSQL and MySql into the same application we may have a problem. I ran into a problem running the Netbeans Entity class wizard to generate my JPA jar. Most of the tables could not be used because the primary keys were not recognized by the wizard. This isn't necessarily a problem, it just means if you want to use JPA, you have to hand code the classes in Java. If you are using Phobos and you run into this and you do not know Java, you might have to weigh just using jdbc as you can then script the object directly and you do not have to write Java code.<br /><br />Check out the Phobos JPA generator tutorial at <a href="https://phobos.dev.java.net/tutorials/jpagenerator/index.html">https://phobos.dev.java.net/tutorials/jpagenerator/index.html</a><br /><br />On another note, be sure to check out Roberto's blog and his speech he gave at the Web 2.0 conference. the link is <a href="http://weblogs.java.net/blog/robc/archive/2007/04/phobos_at_the_w.html">http://weblogs.java.net/blog/robc/archive/2007/04/phobos_at_the_w.html</a>.<br />Roberto is one of the Sun engineers working on Phobos. He details the impressive speed and features of Phobos. The Phobos team has done a great job.<br /><br />Phobos has the potential to really take off for the average developer if it can continue to integrate into the application stack. The way I view it, is that it sits very well under the presentation layer and works very well as the free flowing glue. The challenge will be, can it wrap the layers below it to make it really easy for the developer working in the Phobos layer. This what Ruby on Rails has done and its usage is skyrocketing. There are many more advantages to the Phobos/Java platform than the rails obviously, but ease of use and productivity are what will make a platform take off.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-8073089559153570346?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com0tag:blogger.com,1999:blog-453476104242814492.post-77923758301393787742007-04-20T21:36:00.000-05:002007-04-20T21:38:51.616-05:00The Power of Phobos and The PlatformI wanted to talk about the power and platform that Phobos offers and how easy it is to use. Let's take an example of wanting to accomplish a simple task like reaching out across the Net in a script and retrieving a web page and sending it back to the browser. <br /><br />The first thing we have to do is figure out a way to reach out across the Net. If we were programming in say asp, we would need to use a com object or dll control as vbscript does not have the power to do that. Phobos does have a library function to accomplish this task, but lets assume that it didn't. What do we do? Hhhhmmmm . . . well every class in Java is available to us, or any Java class that is installed into your Phobos installation for that matter. So in order to solve our problem, I did a quick Google search for a Java example with the terms "Get URL Java" and landed on the following URL: http://www.devdaily.com/java/edu/pj/pj010011/index.shtml<br /><br />Now this example will give us a step by step procedure for doing what we want to do in Java, but we are writing in Javascript. All we have to do is rewrite the example in Javascript. It is quite easy. Here is the code for a Phobos script to do the same thing:<br /><br />********************************************************************<br />//Set status and content type<br />response.setStatus(200);<br />response.setContentType("text/html");<br />// Get writer<br />writer = response.getWriter();<br />// Create the URL object<br />var u = java.net.URL("http://192.168.0.76/");<br />// Open an input stream from the url.<br />var is = u.openStream(); // throws an IOException<br />// Convert the InputStream to a buffered DataInputStream. //<br />// Buffering the stream makes the reading faster; the //<br />// readLine() method of the DataInputStream makes the reading //<br />// easier.<br />var dis = java.io.DataInputStream(java.io.BufferedInputStream(is));<br />// Now just read each record of the input stream, and print it out.<br />while ((s = dis.readLine()) != null) {<br /> writer.println(s);<br />}<br />//Close the InputStream<br />is.close();<br />// Flush to the browser<br />writer.flush();<br />*************************************************************************<br /><br />See how easy that is! Using Java classes just like they are native to Javascript. Now, we should do some error trapping and other checking, but the code above illustrates how incredibly easy it is to use Java classes. <br /><br />Another great benefit of using Phobos and Java for that matter is the Java Virtual Machine. It is so powerful, you sometimes forget what it is doing for you. For example, I developed a stub application on a 32 bit workstation and tested and ran it. I then deployed it to a 64 bit dual processor Windows server running the Sun Glassfish Application Server and of course it ran flawlessly. I also deployed to a Linux server running Glassfish and it ran the same. Portability and power available to every developer!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-7792375830139378774?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com0tag:blogger.com,1999:blog-453476104242814492.post-6241590014084458852007-04-16T22:16:00.000-05:002007-04-16T22:23:13.626-05:00Phobos and the Java platform . . .Phobos has been getting more coverage lately and hopefully will continue to receive more in the near future. I believe Sun is on the right track to make a really good, lightweight, scripting stack for the average developer.<br /><br /> I think one of the biggest hindrances for Sun in years past was their lack of vision for reaching out to every business or developer. I think that has changed the last few years and they are on the right track on converting developers and businesses to their software. I have been a fan of Sun's for years even though I have used very little of their software. The biggest problem being ease of use and simplicity. Everyone knows that many, many huge enterprise applications run on Solaris and Java. However, for small business, it is a different ball game and it is hard to utilize all that power and stability. Java was originally written as a replacement for C. While Java was easier than C, a VB, VFP, Perl, or PHP developer wasn't really interested in learning C or Java. Yes, Java was more powerful, but the other languages were simple enough for the masses to crank out simple to somewhat complex applications. Java developers touted for years how great Java was, but you didn't see developers who were comfortable using higher level languages migrating down to Java.<br /><br /> This brings us to Java's opportunity which is now. Microsoft has discontinued VB6, VFP, and Access and is pushing their developers to migrate down to VB.NET or C#. Many developers would rather not do this. They are looking for alternatives. With tools like Phobos and Jmaki for the web, the landscape is looking better for those developers. I am looking forward to Netbeans 6 and the automatic databinding for the fat client, but I think the killer app would be to be able to use the Netbeans IDE tools for fat client, but be able to write your code in Javascript or a higher level language. When the masses can crank out simple applications to meet their needs, you will see migrations of developers who are looking to be able to develop cross platform apps.<br /><br />I have seen some comments about Phobos from Java developers who feel we do not need another Java based web framework. I think Java developers should reach out to those who are not using Java and strive to encourage their movement to the Java platform. The Java community needs to show that it is reaching out to all developers. It has been a great stride for other languages to be ported to the Java platform.<br /><br /> Linux has achieved ease of use for the masses, but the lack of easy developer tools for the average developer to write applications to run on Linux has inhibited its growth. I think a Java foundation with high level languages can fulfill that role. Solaris is an outstanding operating system, but until it can be loaded on generic hardware as easy as Linux or Windows, it is difficult for people to use.<br /><br /> If you are currently using a Microsoft platform, you should give Phobos and the Java platform a try. Join the mailing lists and try writing a simple application. The Sun engineers answer questions and are a great help.<br /><br /> Next week I will discuss the similarities script developers on a Microsoft platform will find on the Phobos platform.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-624159001408445885?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com0tag:blogger.com,1999:blog-453476104242814492.post-52651878290012751992007-04-09T22:41:00.000-05:002007-04-09T23:19:33.455-05:00Phobos Ajax Site Layout<p><span style="font-size:100%;">Here is an example of a simple Ajax layout. This example will show how simple it is to do Ajax with Phobos and how little code it requires. Also, it should be noted, how clear the separation of logic and presentation is by following the Phobos architecture. In order to follow the logic, you should be familiar with the Phobos architecture of controllers and views. Let's get started.<br /></span></p><span style="font-size:100%;">We have a main controller which is commented below. Here is the code.</span><br /><br />// Main controller for the application.<span style="color: rgb(102, 102, 102);"><br />// define a controller module called "main"</span><br /><p><span style="color: rgb(0, 102, 255);"> library.common.define(controller, "main", function() {<br /> <span style="color: rgb(102, 102, 102);">// controller class (constructor)</span><br /> this.Main=function() {<br /> <span style="color: rgb(102, 102, 102);">// insert instance initialization code here<br /> // "show" action method</span><br /> this.show = function() {<br /> <span style="color: rgb(102, 102, 102);">//Use the model global variable to pass information to the view</span>.<br /> model = {};<br /> <span style="color: rgb(102, 102, 102);"> // render the /application/view/main.ejs view</span><br /> library.view.render({view: "home.ejs",<br /> layout: "main.ejs"});<br />}<br /> <span style="color: rgb(102, 102, 102);"> //navigate function: routes and renders the view requested<br /></span></span><span style="color: rgb(0, 102, 255);"> <span style="color: rgb(102, 102, 102);"> //This method is used for Ajax call to update the center section of the layout.</span><br /> this.navigate = function()<br /> {<br /> <span style="color: rgb(102, 102, 102);"> //Get the parameter for which view to render and send back</span><br /> var strUrl = String(request.getParameter("url"));<br /> <span style="color: rgb(102, 102, 102);"> //render the requested view back to the client</span><br /> library.view.render({view:strUrl});<br /> }<br /> };<br /> });</span></p><span style="color: rgb(0, 0, 0);">That's it! That is all the controller code we need for an Ajax layout.</span><br /><br />Our layout is a two column layout with a header, but you can do the same thing with any layout. We have one core file which makes up the structure of our layout. This is main.ejs. This is our main view. Here is the code for it.<br /><br /><html><br /><head><link rel="stylesheet" href=<%= library.view.quoteUrl("/jmaki-standard.css") %> type="text/css"></link><br /><p><span style="color: rgb(0, 102, 255);"><title>Page Title</title><br /><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /><br /><script type="text/javascript"><br />var req;<br />var isIE;<br />var list;<br />var entryField;<br /><br /><span style="color: rgb(153, 153, 153);">// This function will take care of the cal backs to the server<br />// You will notice that once it gets the data back, it sets the innerHtml for the main content<br />// section of the layout.</span></span><span style="color: rgb(0, 102, 255);"><br /></span><span style="color: rgb(0, 102, 255);"> function initRequest(url) {<br /> var list = document.getElementById("list");<br /> if (window.XMLHttpRequest) {<br /> req = new XMLHttpRequest();<br /> } else if (window.ActiveXObject) {<br /> isIE = true;<br /> req = new ActiveXObject("Microsoft.XMLHTTP");<br /> }<br /><br /> req.onreadystatechange = processRequest;<br /> req.open("POST", url, true);<br /> req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");<br /> req.send(null);</span></p> <span style="color: rgb(51, 102, 255);"> function processRequest () {</span><br /><span style="color: rgb(51, 102, 255);"> if (req.readyState == 4) {</span><br /><span style="color: rgb(51, 102, 255);"> if (req.status == 200) {</span><br /><span style="color: rgb(51, 102, 255);"> document.getElementById("maincontent").innerHTML = req.responseText;</span><br /><span style="color: rgb(51, 102, 255);"> }</span><br /><span style="color: rgb(51, 102, 255);"> }</span><span style="color: rgb(51, 102, 255);"><br /> }</span><br /><span style="color: rgb(51, 102, 255);">}</span><br /><p><span style="color: rgb(0, 102, 255);"><span style="color: rgb(153, 153, 153);">//This function will be called by every hyperlink with a parameter of which view we want rendered.<br /><br />//After it assembles the URL, it will call the Request function to get the view from the server.</span><br /></span><span style="color: rgb(0, 102, 255);"> function<br /> submitData(strUrl) {<br /> var url = <%= library.view.quoteUrl("/main/navigate") %> + "?url=" + strUrl;<br /> initRequest(url);<br /> }<br /> </script><br /> </head><br /> <body><br /> <div class="outerBorder"><br /> <div class="header"><br /> <div class="banner">Application Name</div><br /> <div class="subheader"><br /> <div><br /> <a<br /> href="javascript:submitData('feedback.ejs')">Feedback</a> |<br /> <a href="javascript:submitData('sitemap.ejs')">Site<br /> Map</a> |<br /> <a<br /> href="javascript:submitData('home.ejs')">Home</a><br /> </div><br /> </div> <!-- sub-header --><br /> </div> <!-- header --><br /> <div class="main"><br /> <div class="leftSidebar"><br /> Sidebar Content Here<br /> </div> <!-- leftSidebar --><br /> <div class="content" style="height:400px" id="maincontent"><br /> <% library.view.layoutContent(); %><br /> </div> <!-- content --><br /> </div> <!-- main --><br /> </div> <!-- outerborder --><br /> </body><br /> </html></span></p>Notice how each of our hyperlinks call the submitData function with the name of the view they link to. They do not need a path to a file, just the view name. After the functions complete, The main content section will display the view without refreshing the page.<br /><p>All that is left is the three files which the above links reference. Here they are.</p>The home.ejs file contains: <span style="color: rgb(51, 102, 255);"><p>Hello! This is the home page</p></span><br />The feedback.ejs contains: <span style="color: rgb(51, 102, 255);"><p>Hello from the feedback page</p></span>;<br />The sitemap.ejs contains: <span style="color: rgb(51, 102, 255);"><p>Hello from the sitemap page</p></span><br /><br />With this foundation, we can build any number of pages and load them without redisplaying the whole page. We might should add a few more things like a progress bar and a custom back button.<br /><br />I hope to move to a web server and web pages soon so that the formatting for the code will be much more readable, but you get the basic idea.<br /><br />Happy coding!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-5265187829001275199?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com0tag:blogger.com,1999:blog-453476104242814492.post-18026370663729208092007-04-05T21:03:00.000-05:002007-04-05T21:05:21.810-05:00Phobos Appeal And Killer AppsI haven't had time to work with Phobos this week, but I am hoping to design an Ajax layout for a simple forum soon. <br /> In my mind's wandering this week I was thinking about how Phobos could appeal to and be adopted on a large scale. A few things came to mind. It must appeal to the average scripter by providing easy data access to open source databases. It must be supported by web hosts as the average scripter is not using a dedicated server. It also must be marketed as a scripting platform that has ease of use as well as stability and speed.<br /> At this point, I think if a developer takes the time to explore Phobos, they will see that it is a very conducive scripting platform. You can essentially plug in any scripting language and modify the platform to your needs. The database access is easy, but it does require the NetBeans IDE to avoid writing Java code.<br /> Support by web hosts should be easy. Java web hosting is much more common than it was five years ago and is just as cheap as any other hosting. A web host could even market a solution as a javascript server platform. They could bundle in a few specific Java objects and deploy a basic Phobos web app. The customer could script their solution right inside Phobos without ever needing to deploy a web app or know what it is. This should also cure the reasoning of some that Java in a shared environment is not as stable as PHP. As long as Phobos doesn't hiccup, errors in code shouldn't matter. <br /> The killer app for Phobos as a platform would be a Visual IDE. The JMaki project is really exciting from the fact that you can create your own components using simple text tools such as html, css and then of course javascript. This combined with the simplicity of Phobos is very powerful. The killer app would be if Netbeans had a visual layout screen similar to the NetBeans Visual WebPack or Visual Studio, but instead of custom controls written for an IDE, you could use Jmaki controls. Then the average web developer could create their own components for visual layout as well as script their pages.<br /> After this was done the next killer app would be to be able to wrap Phobos up into a single window application with the embedded browser engine. Like the Gecko engine from FireFox. You would be able to write a desktop application with a scripting language using html widgets and of course it would be Internet enabled as it could make calls to servers or databases. You would also have a built in database engine for desktop apps using Derby. Now with one stack, you can write desktop apps, web apps, or Ajax apps with a scripting language, and these apps would be cross platform.<br /> Phobos presents lots of possibilities.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-1802637066372920809?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com0tag:blogger.com,1999:blog-453476104242814492.post-29756528509270753362007-03-24T20:27:00.000-05:002007-03-27T09:47:02.056-05:00Starting a New Project<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_B9EkTe6F4VU/RgiPA7Ka0dI/AAAAAAAAAAk/xLj2uIKgpxA/s1600-h/files.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp3.blogger.com/_B9EkTe6F4VU/RgiPA7Ka0dI/AAAAAAAAAAk/xLj2uIKgpxA/s200/files.jpg" alt="" id="BLOGGER_PHOTO_ID_5046440628512805330" border="0" /></a> I am going to start a new project with Phobos so I can become familiar with how to write a web site and convert existing web sites to the Java platform. The first thing I did was read the Phobos overview located at the following URL https://phobos.dev.java.net/overview.html. If you come from a Java background the architecture is probably familiar to you. If you have been programming purely with html pages and script engines, the architecture may be a little confusing. It took me a few times through the documentation to get a few basic concepts.<br />So let's start with the first thing every web site needs and that is a layout. We will use the default jmaki layout for our sample app. If you start a new project in Netbeans and choose the default Phobos app you will be prompted to choose a layout. Choose any layout and click finish.<br />You will notice that I have an extra directory which was not created by the wizard called dynamic. Add this if you are planning to do this example. The Phobos team will be adding this soon. The dynamic folder along with the ejsp file extension is a new feature that is not in the documentation yet. It is a special folder which is accessed by the system whenever a file with the ejsp extension is requested. You can put any type of file in there and use it to script just like you would ASP or PHP. This is important to note as this is not the standard procedure for Java type applications.<br />Before we go into detail about the mechanics, lets follow a classic ASP example of how we would write a basic page with a layout. The default home page for the application is /script/index.js. Here is the code for it currently:<br /><br /><span style="color: rgb(51, 102, 255);">/* This script is called when the client tries to access the "/" URL.</span><br /><span style="color: rgb(51, 102, 255);"> * It simply redirects to a URL that causes the main application page</span><br /><span style="color: rgb(51, 102, 255);"> * to be displayed.</span><br /><span style="color: rgb(51, 102, 255);"> */</span><br /><span style="color: rgb(51, 102, 255);">// default index is to activate the main controller or page:</span><br /><span style="color: rgb(51, 102, 255);">library.httpserver.sendRedirect(library.httpserver.makeUrl("default.ejsp"));<br /><br /><span style="color: rgb(0, 0, 0);"> We are simply using the two library functions to redirect the browser to our home page. Because we used the ejsp extension, Phobos knew to look in the dynamic directory for the file. We did not have to give it a full path.<br />The code for our home page looks like this:<br /><br /><span style="color: rgb(51, 102, 255);"><% library.view.include("/application/dynamic/header.ejs"); %></span><br /><span style="color: rgb(51, 102, 255);"><p>Hello from embedded Javascript running on a JDK</p></span><br /><span style="color: rgb(51, 102, 255);"><% library.view.include("/application/dynamic/footer.ejs"); %><br /><br /><span style="color: rgb(0, 0, 0);"> The </span></span></span></span><span style="color: rgb(51, 102, 255);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(51, 102, 255);">library.view.include <span style="color: rgb(0, 0, 0);">function includes content from another file just like and include directive in ASP or PHP. So we included our header and footer and put our main content in between. We did have to provide the full path to the files because the extension is ejs. We could have just used the file name if our header and footer were located in the view directory. Phobos would have found them for us in that case.<br />When creating hyperlinks in our main content, we can link directly to file names in the dynamic folder and include our layout like we did above. This is typically how scripting has worked on the web and what scripters are used to.<br /><br />Now we will look at how Java typically has done the same thing so we can understand the whole Phobos framework. You will notice in the directory layout that we have a controller folder and a view folder. In Java, you would use what they call a Model View Controller framework</span></span></span></span><span style="color: rgb(51, 102, 255);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(51, 102, 255);">. <span style="color: rgb(0, 0, 0);">If you are trying to visualize with the layout page in mind compared to the example above, what you need to understand is that we essentially link to the same controller ("file") with our hyperlinks and swap out the center content section of the page. This has its advantages as you will see as we progress, and it is still very flexible.<br /><br />So with MVC we always have at least two files. We have the controller and the view. The model is the data shared between the two. In our controller we would put all of our script code and then paint the view. The view can have presentation code in it as well and adjust itself based on the data in the model. Here is the modified code for the index.js when we are going to use the controller:<br /><br /><span style="color: rgb(51, 102, 255);">/* This script is called when the client tries to access the "/" URL.</span><br /><span style="color: rgb(51, 102, 255);"> * It simply redirects to a URL that causes the main application page</span><br /><span style="color: rgb(51, 102, 255);"> * to be displayed.</span><br /><span style="color: rgb(51, 102, 255);"> */</span><br /><span style="color: rgb(51, 102, 255);">// default index is to activate the main controller or page:</span><br /><span style="color: rgb(51, 102, 255);">library.httpserver.sendRedirect(library.httpserver.makeUrl("/main/show"));</span><br /><br /><span style="color: rgb(0, 0, 0);">Here we are sending a redirect, and Phobos knows where the controllers are so we do not have to give it the path. We are calling the show method of the controller.<br /><br />Here is the code for the main controller:<br /><br /><span style="color: rgb(51, 102, 255);">/*</span><br /><span style="color: rgb(51, 102, 255);"> * Main controller for the application.</span><br /><span style="color: rgb(51, 102, 255);"> *</span><br /><span style="color: rgb(51, 102, 255);"> * This file was generated, please edit it as needed.</span><br /><span style="color: rgb(51, 102, 255);"> */</span><br /><span style="color: rgb(51, 102, 255);">// define a controller module called "main"</span><br /><span style="color: rgb(51, 102, 255);">library.common.define(controller, "main", function() {</span><br /><span style="color: rgb(51, 102, 255);"> // controller class (constructor)</span><br /><span style="color: rgb(51, 102, 255);"> function Main() {</span><br /><span style="color: rgb(51, 102, 255);"> // insert instance initialization code here</span><br /><span style="color: rgb(51, 102, 255);"> }</span><br /><span style="color: rgb(51, 102, 255);"> // "show" action method</span><br /><span style="color: rgb(51, 102, 255);"> Main.prototype.show = function() {</span><br /><span style="color: rgb(51, 102, 255);"> /*</span><br /><span style="color: rgb(51, 102, 255);"> Use the model global variable to pass information to the view.</span><br /><span style="color: rgb(51, 102, 255);"> Alternatively, a view can access the controller instance by</span><br /><span style="color: rgb(51, 102, 255);"> using the expression:</span><br /><span style="color: rgb(51, 102, 255);"> invocation.controller</span><br /><span style="color: rgb(51, 102, 255);"> */</span><br /><span style="color: rgb(51, 102, 255);"> model = {};</span><br /><span style="color: rgb(51, 102, 255);"> // render the /application/view/main.ejs view</span><br /><span style="color: rgb(51, 102, 255);"> //library.view.render("main.ejs");</span><br /><span style="color: rgb(51, 102, 255);"> library.view.render({view: "mainContent.ejs",</span><br /><span style="color: rgb(51, 102, 255);"> layout: "main.ejs"});</span><br /><span style="color: rgb(51, 102, 255);"> }</span><br /><span style="color: rgb(51, 102, 255);"> // export the controller class</span><br /><span style="color: rgb(51, 102, 255);"> this.Main = Main;</span><br /><span style="color: rgb(51, 102, 255);">});<br /><br /><span style="color: rgb(0, 0, 0);">Consider this commented line:</span></span></span></span></span></span></span><span style="color: rgb(51, 102, 255);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(51, 102, 255);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(51, 102, 255);"></span><br /><span style="color: rgb(51, 102, 255);"> //library.view.render("main.ejs");<br /><span style="color: rgb(0, 0, 0);">This line would have rendered the view called main.ejs. However, we can have a layout file and a different file with the content for the main section. These commands will render both files:<br /></span></span></span></span></span></span></span><span style="color: rgb(51, 102, 255);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(51, 102, 255);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(51, 102, 255);"> library.view.render({view: "mainContent.ejs",</span><br /><span style="color: rgb(51, 102, 255);"> layout: "main.ejs"});<br /><span style="color: rgb(0, 0, 0);">The </span></span></span></span></span></span></span><span style="color: rgb(51, 102, 255);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(51, 102, 255);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(51, 102, 255);">mainContent.ejs <span style="color: rgb(0, 0, 0);">is the center section of the page and the </span></span></span></span></span></span></span><span style="color: rgb(51, 102, 255);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(51, 102, 255);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(51, 102, 255);">main.ejs <span style="color: rgb(0, 0, 0);">is the layout.<br /><br />The main views are just made up of html except that in the layout where the center content is placed, you place a function call with the following line:<br /><br /><span style="color: rgb(51, 102, 255);"><% library.view.layoutContent(); %></span><br /><br />I hope this has shown that Phobos can act like a traditional script engine and is flexible. I have attempted also to explain the semantics behind the MVC pattern which is a much powerful and maintainable when writing large applications.<br /><br /></span></span></span></span></span></span></span><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/453476104242814492-2975652850927075336?l=phobosblog.zakula.com'/></div>Tony Zakulahttp://www.blogger.com/profile/06184625873502267392noreply@blogger.com0