Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7019 Articles
article-image-mastering-phpmyadmin-4-editions-5-years
Packt
20 Oct 2009
4 min read
Save for later

Mastering phpMyAdmin: 4 Editions in 5 years

Packt
20 Oct 2009
4 min read
Among the daily deluge of spam, sometimes there is a real email – and sometimes even an important one. I received such an email at the end of October 2003 from Louay Fatoohi, presenting himself as the Editorial Director of a new publishing company, Packt Publishing. He was asking if I would be interested in writing a book about phpMyAdmin (which is a web interface for the MySQL database). At this time, our software product was already popular with about 150,000 downloads per month, but the lack of serious and complete user documentation held it back. This translated into many requests from users about how to accomplish some tasks with the software. Moreover, the small team of five active developers (all volunteers) was using all its free time for planning and coding new features so we did not see how to improve the documentation with volunteer work only. I did not know Mr Fatoohi but his email (and the following ones) looked serious so I committed myself to this project. I noticed that producing a clear book outline was very important. I already had in mind that each chapter should focus on a specific task or group of similar tasks. In the next days, a few iterations of the outline were done to balance the chapter lengths. Receiving a paper contract from England was new for me – in fact the whole process felt new to me as this was my first book. Writing for others is challenging and dealing with the comments of reviewers and editors can be a humbling experience; I had to defend some ideas I had put in the book but gladly accepted suggestions for improvement or clarification. It took about three months, working over the weekends (I have a day job) to write the first edition, Mastering phpMyAdmin for Effective MySQL Management, which was published in April 2004. Since this manual covers the complete interface, I was in fact testing the whole software, finding bugs along the way, which forced me to fix them in order to produce correct screenshots! Needless to say, I was very proud of being the first published author for this company. Meanwhile, an interface redesign was taking place in phpMyAdmin for version 2.6.0; this meant that many screenshots in the book would no longer reflect the upcoming version of the software. The decision was made by Packt to publish a book update. During the summer of 2004, I already knew what the new version would look like so I started preparing this update. The new version of the software was released at the end of September and the book update (bearing the same ISBN as the first edition) somewhere in October! In June 2005 we organized the first phpMyAdmin team meeting in Germany during the LinuxTag event where we demoed our software. I was happy to meet Mr Fatoohi, Damian Carvill and other representatives from Packt who had a booth there too. I found the whole team very dynamic and very much readers-oriented. I know that publishing is a business but they understand that quality is important; they also respect me as an author (especially about schedules). Over the years, translations of the book were published, directly by Packt or via other publishers. I wrote the French version, while two phpMyAdmin developers did the German one. Versions in Czech, Italian and Spanish were also born and they are all proudly displayed in my house near the workstation. Meanwhile, phpMyAdmin’s march was continuing, with an average of 250,000 downloads per month. It should be noted that many users do not need to download it directly because host providers install the software for them, or Linux distributors include it on their DVD, this is why we cannot know exactly the number of users. The development team changed a bit but new features were appearing so I guess Packt Publishing resigned itself about the need to update this title from time to time. This is why I took to my pencil again – rather my keyboard – to produce the October 2006 edition, Mastering phpMyAdmin 2.8 which covered a new setup mechanism. In March 2008, Mastering phpMyAdmin 2.11 was published, followed by Mastering phpMyAdmin 3.1 in March 2009. My family is now accustomed to my new habit of taking a few weeks per year to produce the new update. I would like to express my wholeheartedly gratitude to Packt Publishing for their support into this ongoing project. --Marc Delisle
Read more
  • 0
  • 0
  • 4612

article-image-rotating-post-titles-post-preview-gadget
Packt
20 Oct 2009
6 min read
Save for later

The Rotating Post Titles with Post Preview Gadget

Packt
20 Oct 2009
6 min read
The Rotating Post Titles with Post Preview gadget lists all your blog posts classified according to labels or categories. Blogger uses Labels to classify posts while Wordpress uses Categories for the same. Clicking on a Label or a category in the sidebar of a blog brings up all posts associated with that particular label or category. However, you will see only posts associated with that one label. In this gadget post titles are grouped under their respective labels. In this gadget in one look you can see all the post titles in that blog and all the labels in it. Thus you get a full summary of the blog. Hovering on a post title shows the Post Preview in the top pane. You can then click on it to go to that post to read it in full detail. What is Google AJAX feed API? AJAX (shorthand for asynchronous JavaScript and XML) is a web development technique which retrieves data from the server asynchronously in the background without interfering with the display, and behaviour of the existing page. The whole page is not refreshed when data is retrieved. Only that section of the page which is a part of the gadget shows the data brought. With the Google AJAX Feed API, you can retrieve feeds and mash them up using Javascript. In this gadget, we will retrieve the post titles from the label feeds and display them using Javascript code. See picture below: This gadget shows list of posts grouped by label from my blog http://www.blogdoctor.me. Four post titles from three labels are shown but the code can be modified to show all posts from all labels (categories). This label is also shown as Gadget No 4 in My Gadget Showcase blog. The cursor autoscrolls down the post titles, and each post preview is shown at the top as an excerpt for five seconds before moving on to the next post. Obtaining the Google AJAX API Key The first step in installing the above gadget is to get the Google AJAX API Key. It is free and you can easily obtain it for any site blog or page by signing up for the key at the API key signup page. Type in your blog address in the My web site URL text box and click the "Generate API Key" button. On the resulting page copy the key and paste it in code below as shown. Customizing the code In the code below replace PASTE AJAX API KEY HERE with your actual key obtained above. <!-- ++Begin Dynamic Feed Wizard Generated Code++ --><!-- // Created with a Google AJAX Search and Feed Wizard // http://code.google.com/apis/ajaxsearch/wizards.html --> <!-- // The Following div element will end up holding the actual feed control. // You can place this anywhere on your page. --><div id="content"> <span style="color:#676767;font-size:11px;margin:10px;padding:4px;">Loading...</span> </div><!-- Google Ajax Api --> <script src="http://www.google.com/jsapi?key=PASTE AJAX API KEY HERE" type="text/javascript"></script> <!-- Dynamic Feed Control and Stylesheet --> <script src="http://www.google.com/uds/solutions/dynamicfeed/gfdynamicfeedcontrol.js" type="text/javascript"></script> <style type="text/css"> @import url("http://www.google.com/uds/solutions/dynamicfeed/gfdynamicfeedcontrol.css"); </style><script type="text/javascript"> google.load('feeds', '1'); function OnLoad() { var feeds = [ { title: 'LABEL_1', url: 'http://MYBLOG.blogspot.com/feeds/posts/default/-/LABEL1?max-results=100' }, { title: 'LABEL_2', url: 'http://MYBLOG.blogspot.com/feeds/posts/default/-/LABEL2?max-results=100' }, { title: 'LABEL_3', url: 'http://MYBLOG.blogspot.com/feeds/posts/default/-/LABEL3?max-results=100' } ]; var options = { stacked : true, horizontal : false, title : "Posts from BLOG_TITLE" }; new GFdynamicFeedControl(feeds, 'content', options); document.getElementById('content').style.width = "200px"; } google.setOnLoadCallback(OnLoad); </script> In the above code replace LABEL_1, LABEL_2 and LABEL_3 and LABEL1, LABEL2 and LABEL3 by respective Label Names and BLOG_TITLE by the actual title of your blog. Also replace MYBLOG by actual blog subdomain. This is for blogspot blogs only. For Wordpress blog you will have to replace the label feeds:: http://MYBLOG.blogspot.com/feeds/posts/default/-/LABEL1?max-results=100 http://MYBLOG.blogspot.com/feeds/posts/default/-/LABEL2?max-results=100 http://MYBLOG.blogspot.com/feeds/posts/default/-/LABEL3?max-results=100 by the Category feed URLs from Wordpress blog. After customizing the above code in Blogger paste it in a HTML gadget while in Wordpress paste it in a Text widget. Further Customization To show more than four posts per label or category, you will have to modify the following Javascript code file: http://www.google.com/uds/solutions/dynamicfeed/gfdynamicfeedcontrol.js In the above mentioned Javascript code file, alter the following code line in it : GFdynamicFeedControl.DEFAULT_NUM_RESULTS = 4; Change '4' to '1000' and save the file as a MODgfdynamicfeedcontrol.js file in a text editor like Notepad. Upload the file to a free host and replace the link of the file in the above code. To change the styling of the gadget, you will have to modify the following file: http://www.google.com/uds/solutions/dynamicfeed/gfdynamicfeedcontrol.css Then save the modified file and upload it to a free host and replace its link in the above code. Working Example Posts from The Blog Doctor Change Post Formatting According to Author. by Vin - 30 Apr 2008 If you have a Team Blog made up of two authors you can change the formatting of the posts written by one author to ... Template Calling all Newbie Bloggers! Upgrade Classic Template without the "UPGRADE YOUR TEMPLATE" button. The Minimalist Minima Photoblog Template. Making the COMMENTS Link more User Friendly. CSS Change Post Formatting According to Author. Free CSS Navigation Menus in Blogger. Fix the Page Elements Layout Editor No Scrollbar Problem. Frame the Blog Header Image. Blogger Hacks Rounded Corner Headers for Blogger. Timestamp under the Date and Other Hacks. Add Icon to Post Titles. Many Headers In One Blog.   Summary The Rotating Post Titles with Post Preview gadget provides an at-a glance summary of your blog. All the posts are grouped by label or category and are linked to their post pages. The constantly rotating post excerpts at the top draws the attention of the reader and gets him/her more involved and eager to explore your blog. This increases the traffic and decreases the bounce rate of visitors from your blog.nara
Read more
  • 0
  • 0
  • 3925

article-image-er-diagrams-domain-model-and-n-layer-architecture-aspnet-35-part1
Packt
20 Oct 2009
11 min read
Save for later

ER Diagrams, Domain Model, and N-Layer Architecture with ASP.NET 3.5 (part1)

Packt
20 Oct 2009
11 min read
Let us start with a 1-tier ASP.NET application configuration. Note that the application as a whole including database and client browser is three tier. We can call this 1-tier architecture a 3-tier architecture if we include the browser and database (if used). For the rest of this article we will ignore the database and browser as separate tiers so that we can focus on how to divide the main ASP.NET application layers logically, using the n-layer pattern to its best use. We will first try to separate the data access and logical code into their own separate layers and see how we can introduce flexibility and re-usability into our solution. We will understand this with a sample project. Before we go ahead into the technical details and code, we will first learn about two important terms: ER Diagram and Domain Model, and how they help us in getting a good understanding of the application we need to develop. Entity-Relationship Diagram Entity-Relationship diagrams, or ER diagrams in short, are graphical representations depicting relationships between different entities in a system. We humans understand and remember pictures or images more easily than textual information. When we first start to understand a project we need to see how different entities in the project relate to each other. ER diagrams help us achieve that goal by graphically describing the relationships. An entity can be thought of as an object in a system that can be identified uniquely. An entity can have attributes; an attribute is simply a property we can associate with an entity. For example, a Car entity can have the following attributes: EngineCapacity, NumberofGears, SeatingCapacity, Mileage, and so on. So attributes are basically fields holding data to indentify an entity. Attributes cannot exist without an entity. Let us understand ER diagrams in detail with a simple e-commerce example: a very basic Order Management System. We will be building a simple web based system to track customer's orders, and manage customers and products. To start with, let us list the basic entities for our simplified Order Management System (OMS): Customer: A person who can place Orders to buy Products. Order: An order placed by a Customer. There can be multiple Products bought by a Customer in one Order. Product: A Product is an object that can be purchased by a Customer. Category: Category of a Product. A Category can have multiple Products, and a Product can belong to many Categories. For example, a mixer-grinder can be under the Electronic Gadgets category as well as in Home Appliances. OrderLineItem: An Order can be for multiple Products. Each individual Product in an order will be encapsulated by an OrderLineItem. So an Order can have multiple OrderLineItems. Now, let us picture the relationship between the core business entities is defined using an Entity-Relationship diagram. Our ER diagram will show the relational associations between the entities from a database's perspective. So it is more of a relational model and will not show any of the object-oriented associations (for which we will use the Domain Model in the later sections of this article). In an ER diagram, we show entities using rectangular boxes, the relationships between entities using diamond boxes and attributes using oval boxes, as shown below: The purpose of using such shapes is to make the ER diagram clear and concise, depicting the relational model as closely as possible without using long sentences or text. So the Customer entity with some of the basic attributes can be depicted in an ER diagram as follows: Now, let us create an ER diagram for our Order Management System. For the sake of simplicity, we will not list the attributes of the entities involved. Here is how the ER diagram looks: The above ER diagram depicts the relationships between the OMS entities but is still incomplete as the relationships do not show how the entities are quantitatively related to each other. We will now look at how to quantify relationships using degree and cardinality. Degree and Cardinality of a Relationship The relationships in an ER diagram can also have a degree. A degree specifies the multiplicity of a relationship. In simpler terms, it refers to the number of entities involved in a relationship. All relationships in an OMS ER diagram have a degree of two, also called binary relationships. For example, in Customer-Order relationships only two entities are involved—Customer and Order; so it's a two degree relationship. Most relationships you come across would be binary. Another term associated with a relationship is cardinality. The cardinality of a relationship identifies the number of instances of entities involved in that particular relationship. For example, an Order can have multiple OrderLineItems, which means the cardinality of the relationship between Order and OrderLineItem is one-to-many. The three commonly-used cardinalities of a relationship are: One-to-one: Depicted as 1:1Example: One OrderLineItem can have only one Product; so the OrderLineItem and Product entities share a one-to-one relationship One-to-many: Depicted as 1:nExample: One customer can place multiple orders, so the Customer and Order entities share a one-to-many relationship Many-to-many: Depicted as n:mExample: One Product can be included in multiple Categories and one Category can contain multiple Products; therefore the Product and Category entities share a many-to-many relationship After adding the cardinality of the relationships to our ER diagram, here is how it will look: This basic ER diagrams tells us a lot about how the different entities in the system are related to each other, and can help new programmers to quickly understand the logic and the relationships of the system they are working on. Each entity will be a unique table in the database. OMS Project using 2-Layer We know that the default coding style in ASP.NET 2.0 already supports the 1-tier 1-layer style, with two sub-layers in the main UI layer as follows: Designer code files: ASPX markup files Code behind files: Files containing C# or VB.NET code Because both of these layers contain the UI code, we can include them as a part of the UI layer. These two layers help us to separate the markup and the code from each other. However, it is still not advisable to have logical code, such as data access or business logic, directly in these code-behind files. Now, one way to create an ASP.NET web application for our Order Management System (OMS) in just one layer is by using a DataSet (or DataReader) to fill the front-end UI elements directly in the code-behind classes. This will involve writing data access code in the UI layer (code-behind), and will tightly bind this UI layer with the data access logic, making the application rigid (inflexible), harder to maintain, and less scalable. In order to have greater flexibility, and to keep the UI layer completely independent of the data access and business logic code, we need to put these elements in separate files. So we will now try and introduce some loose-coupling by following a 2-layer approach this time. What we will do is, write all data access code in separate class files instead of using the code-behind files of the UI layer. This will make the UI layer independent of the data-access code. We are assuming that we do not have any specific business logic code at this point, or else we would have put that under another layer with its own namespace, making it a 3-layered architecture. We will examine this in the upcoming sections of this article. Sample Project Let us see how we can move from this 1-tier 1-layer style to a 1-tier 2-layer style. Using the ER diagram above as reference, we can create a 2-Layer architecture for our OMS with these layers: UI-layer with ASPX and code-behind classes Data access classes under a different namespace but in the same project So let's start with a new VS 2008 project. We will create a new ASP.NET Web Project in C#, and add a new web form, ProductList.aspx, which will simply display a list of all the products using a Repeater control. The purpose of this project is to show how we can logically break up the UI layer further by separating the data access code into another class file. The following is the ASPX markup of the ProductList page (unnecessary elements and tags have been removed to keep things simple): <asp:Repeater ID="prodRepeater" runat="server"> <ItemTemplate> Product Code: <%# Eval("Code")%> <br> Name: <%# Eval("Name")%> <br> Unit Price: $<%# Eval("UnitPrice")%> <br> </ItemTemplate></asp:Repeater> In this ASPX file, we only have a Repeater control, which we will bind with the data in the code-behind file. Here is the code in the ProductList.aspx.cs code-behind file: namespace OMS{public partial class _Default : System.Web.UI.Page { /// <summary> /// Page Load method /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void Page_Load(object sender, EventArgs e) { DataTable dt = DAL.GetAllProducts(); prodRepeater.DataSource = dt; prodRepeater.DataBind(); } }//end class}//end namespace Note that we don't have any data access code in the code-behind sample above. We are just calling the GetAllProducts() method, which has all of data access code wrapped in a different class named DAL. We can logically separate out the code, by using different namespaces to achieve code re-use and greater architectural flexibility. So we created a new class named DAL under a different namespace from the UI layer code files. Here is the DAL code: namespace OMS.Code{ public class DAL { /// <summary> /// Load all comments from the Access DB /// </summary> public static DataTable GetAllProducts() { string sCon = ConfigurationManager.ConnectionStrings[0].ConnectionString; using (SqlConnection cn = new SqlConnection(sCon)) { string sQuery = @"SELECT * FROM OMS_Product"; SqlCommand cmd = new SqlCommand(sQuery, cn); SqlDataAdapter da = new SqlDataAdapter(cmd); DataSet ds = new DataSet(); cn.Open(); da.Fill(ds); return ds.Tables[0]; } } }//end class}//end namespace So we have separated the data access code in a new logical layer, using a separate namespace, OMS.Code, and using a new class. Now, if we want to, we can re-use the same code in the other pages as well. Furthermore, methods to add and edit a product can be defined in this class and then used in the UI layer. This allows multiple developers to work on the DAL and UI layers simultaneously. Even though we have a logical separation of the code in this 2-layer sample architecture, we are still not using real Object Oriented Programming (OOP). All of the Object-Oriented Programming we have used so far has been the default structure the .NET framework has provided, such as the Page class, and so on. When a project grows big in size as well as complexity, using the 2-layer model discussed above can become cumbersome and cause scalability and flexibility issues. If the project grows in complexity, then we will be putting all of the business logic code in either the DAL or the UI layer. This business logic code includes business rules. For example, if the customer orders a certain number of products in one order, he gets a certain level of discount. If we code such business rules in the UI layer, then if the rules change we need to change the UI as well, which is not ideal, especially in cases where we can have multiple UIs for the same code, for example one normal web browser UI and another mobile-based UI. We also cannot put business logic code in the DAL layer because the DAL layer should only contain data access code which should not be mixed with any kind of business processing logic. In fact the DAL layer should be quite "dumb"–there should be no "logic" inside it because it is mostly a utility layer which only needs to put data in and pull data out from a data store. To make our applications more scalable and to reap the benefit of OOP, we need to create objects, and wrap business behavior in their methods. This is where the Domain Model comes into the picture.
Read more
  • 0
  • 0
  • 10197

article-image-securing-network-services-freebsd-jails
Packt
20 Oct 2009
7 min read
Save for later

Securing Network Services with FreeBSD Jails

Packt
20 Oct 2009
7 min read
Introduction Is it possible to easily run a half-dozen internet services on a single piece of hardware and make sure that if one is compromised the others will remain unharmed? Can this be done without a mountain of administrative overhead and customization? Can I configure my services the way I have grown accustomed? Absolutely! This article will outline how to achieve this, through the use of FreeBSD Jails. Over the course of this article I will outline how to install a list of production services on a single piece of hardware, securing each one from the next, all with only one additional administrative tool: ezjail Before we get to the ezjail tool we need to define FreeBSD Jails. What are they? What do they do? Why do I care? FreeBSD Jails are a kernel-level security tool used widely in the FreeBSD community to segregate processes. An easy way to think of a Jail is that it is very much like a chroot environment, but much more hardened. While a standard chroot environment can often be escaped, FreeBSD has added code to their kernel which hardens the chroot environment into a "Jail"—Inescapable. Within this Jailed environment processes are unable to identify, access or otherwise communicate with processes on the outside of the Jail. Networking is limited within the Jail as well. A Jail cannot affect any underlying network configuration other than that which it has been assigned. A Jail can also be thought of in many ways like a virtualized machine in that the virtual "guest" cannot interact with the physical "host". Jails allow us the opportunity to run processes in a secure manner separate from our host environment. If that sounds appealing to you may be wondering how to activate and use this Jail system. That, my friend, is the focus of this article. Get settled because by the time we're done here you will have all the tools you need to segregate processes for security, sandboxing or even create custom environments for other users. By default the Jail system is part of the FreeBSD kernel. The kernel customizations to make the system possible have such a minimal footprint that it was decided it should be a default, always-on feature of FreeBSD. Your FreeBSD installation already has the ability to do everything described above, you just need to know how to use it. Ezjail The tool that I use to create, manage and interact with my FreeBSD jails is called "ezjail". It simplifies much of the underlying configuration of a Jail system to the extent that you can create a Jail and be working within it in just three steps! To install the ezjail port you need to make sure you have your ports tree updated and then run: cd /usr/ports/sysutils/ezjail && make install clean Before we can create any Jails we'll need to create the base Jail environment. This is the template environment from which all other Jails will be created. This is simplified by the ezjail-admin tool: ezjail-admin install This will download the components of a base Jail system. Also, the -m, -s and -p options install the man pages, source packages and ports tree respectively. If you want access to these within your Jail environments then be sure to append them to the command above. Before any Jails will be able to start you'll also need to activate the ezjail system within the /etc/rc.conf. This is done using the command: echo 'ezjail_enable="YES"' >> /etc/rc.conf" Now that you've got the proper tools installed you'll need to keep in mind the following requirements for creating and maintaining a Jail environment. These items will need to be defined for each Jail environment that you want to create, and will need to persist for the life of the Jail. jailname IP Address(es) custom jailroot (storage directory) - optional For our purposes here we'll create three Jail environments. We'll call them "larry", "curly" and "moe". Each of these will be assigned an IP address on our internal LAN using "192.168.0.100", "192.168.0.101" and "192.168.0.102" respectively. We will also use the default jailroot path, which is /usr/jails/jailname/. Based on the above decisions we have three of the items defined, but only two configured. We will need to create interface aliases for our network device which will bind to the addresses we've decided on. There are two ways this can be done. The first method, the temporary method, will work for quickly testing Jails and creating environments that you don't need to keep. The second method, the persistent method, will define the interface aliases in your system configuration and define them persistently across reboots. The persistent method is what you will need if you plan on continuing to use your Jails long term. Note: FreeBSD defines network interfaces by their device name or module name. Replace hme0 with your interface name as required. Temporary Network Alias To create temporary network aliases for the three Jails you would run these commands (replacing each IP as needed): ifconfig hme0 alias 192.168.0.100 netmask 255.255.255.255ifconfig hme0 alias 192.168.0.101 netmask 255.255.255.255ifconfig hme0 alias 192.168.0.102 netmask 255.255.255.255 Persistent Network Alias To create persistent network aliases (aliases that will persist across reboots) you would add the following to your /etc/rc.conf file (replacing your IP as needed): ifconfig_hme0_alias0="inet 192.168.0.100/32"ifconfig_hme0_alias1="inet 192.168.0.101/32"ifconfig_hme0_alias2="inet 192.168.0.102/32" Creating a Jail environment Once you have activated your network aliases and the third and final configuration requirement is met we're ready to create these Jails. You can create a Jail environment using the command below. Repeat for each Jail, replacing jailname and jailip as needed: ezjail-admin create jailname jailip In this situation we would have run the following commands: ezjail-admin create larry 192.168.0.100ezjail-admin create moe 192.168.0.101ezjail-admin create curly 192.168.0.102 You will see a bunch of output on your screen. This is normal. The output shows that files are being put into place and underlying configuration is happening. Remember, without the ezjail-admin tool you'd need to do that configuration by hand. No thanks! Your Jail environments are now ready to use! Wasn't that easy! To move from you host system to your Jail environment simply use the command: ezjail-admin console jailname This command will give you a console connection into the Jail environment. It will act just as if you had sat down and logged into the machine (although no login credentials are required). You should now be within one of your Jails, logged in as root, with a base FreeBSD system. No ports are installed. Nothing is configured. None of the host customizations are adopted. You have a pristine, minimal FreeBSD installation to begin building your services. Configure and activate SSH Let's configure a service and make this Jail more accessible. First, SSH: SSH is part of the base FreeBSD installation so all we need to do is configure and activate the service. It should work out of the box, but it can't hurt to take a look at the configuration for the SSH daemon, located in /etc/ssh/sshd_config. You may want to update the following lines: ListenAddress 0.0.0.0 For this example we'll change the port to 2200 and the ListenAddress to 192.168.0.100. Update the Jail environment to launch the SSH daemon at startup by adding the following line to your /etc/rc.conf: sshd_enable="YES" Finally, start the service manually by running: /etc/rc.d/sshd start If you now logout of your Jail (type "exit") and take a look at your host system using netstat you should find that it is listening on 192.168.0.100:2200—the host address and port (assuming ssh is configured on the host system). You can find this information using: netstat -nat | less
Read more
  • 0
  • 0
  • 5482

article-image-integrating-zk-other-frameworks
Packt
20 Oct 2009
7 min read
Save for later

Integrating ZK with Other Frameworks

Packt
20 Oct 2009
7 min read
Integration with the Spring Framework Spring is one of the most complete lightweight containers, which provides centralized, automated configuration, and wiring of your application objects. It improves your application's testability and scalability by allowing software components to be first developed and tested in isolation, then scaled up for deployment in any environment. This approach is called the POJO (Plain Old Java Object) approach and is gaining popularity because of its flexibility. So, with all these advantages, it's no wonder that Spring is one of the most used frameworks. Spring provides many nice features: however, it works mainly in the back end. Here ZK may provide support in the view layer. The benefit from this pairing is the flexible and maturity of Spring together with the easy and speed of ZK. Specify a Java class in the use attribute of a window ZUL page and the world of Spring will be yours. A sample ZUL looks like: <?xml version="1.0" encoding="UTF-8"?> <p:window xsi_schemaLocation="http://www.zkoss.org/2005/zul http://www.zkoss.org/2005/zul " border="normal" title="Hello!" use="com.myfoo.myapp.HelloController"> Thank you for using our Hello World Application. </p:window> The HelloController points directly to a Java class where you can use Spring features easily. Normally, if a Java Controller is used for a ZUL page it becomes necessary sooner or later to call a Spring bean. Usually in Spring you would use the applicationContext like: ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDAO userDAO = (UserDAO) ctx.getBean("userDAO"); Then the userDAO is usable for any further access. In ZK there is a helper class SpringUtil. It wrapps the applicationContext and simplifies the code to: UserDAO userDAO = (UserDAO) SpringUtil.getBean("userDAO"); Pretty easy, isn't it? Let us examine an example. Assume we have a small web application that gets flight data from a flight table. The web.xml file looks like: <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xsi_schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>IRT-FLIGHTSAMPLE</display-name> <filter> <filter-name>hibernateFilter</filter-name> <filter-class> org.springframework.orm.hibernate3.support.OpenSessionInViewFilter </filter-class> </filter> <filter-mapping> <filter-name> hibernateFilter </filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext-jdbc.xml ,classpath:applicationContext-dao.xml ,classpath:applicationContext-service.xml ,classpath:applicationContext.xml </param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <session-config> <!-- Default to 30 minute session timeouts --> <session-timeout>30</session-timeout> </session-config> <mime-mapping> <extension>xsd</extension> <mime-type>text/xml</mime-type> </mime-mapping> <servlet> <description> <![CDATA[The servlet loads the DSP pages.]]> </description> <servlet-name>dspLoader</servlet-name> <servlet-class> org.zkoss.web.servlet.dsp.InterpreterServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>dspLoader</servlet-name> <url-pattern>*.dsp</url-pattern> </servlet-mapping> <!-- ZK --> <listener> <description> Used to cleanup when a session is destroyed </description> <display-name>ZK Session Cleaner</display-name> <listener-class> org.zkoss.zk.ui.http.HttpSessionListener </listener-class> </listener> <servlet> <description>ZK loader for ZUML pages</description> <servlet-name>zkLoader</servlet-name> <servlet-class> org.zkoss.zk.ui.http.DHtmlLayoutServlet </servlet-class> <!-- Must. Specifies URI of the update engine (DHtmlUpdateServlet). It must be the same as <url-pattern> for the update engine. --> <init-param> <param-name>update-uri</param-name> <param-value>/zkau</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>zkLoader</servlet-name> <url-pattern>*.zul</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>zkLoader</servlet-name> <url-pattern>*.zhtml</url-pattern> </servlet-mapping> <servlet> <description>The asynchronous update engine for ZK </description> <servlet-name>auEngine</servlet-name> <servlet-class> org.zkoss.zk.au.http.DHtmlUpdateServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>auEngine</servlet-name> <url-pattern>/zkau/*</url-pattern> </servlet-mapping> <welcome-file-list id="WelcomeFileList"> <welcome-file>index.zul</welcome-file> </welcome-file-list> </web-app> Furthermore let's have a small ZUL page that has the interface to retrieve and show flight data: <?xml version="1.0" encoding="UTF-8"?> <p:window xsi_schemaLocation="http://www.zkoss.org/2005/zul http://www.zkoss.org/2005/zul " id="query" use="com.myfoo.controller.SampleController"> <p:grid> <p:rows> <p:row> Airline Code: <p:textbox id="airlinecode"/> </p:row> <p:row> Flightnumber: <p:textbox id="flightnumber"/> </p:row> <p:row> Flightdate: <p:datebox id="flightdate"/> </p:row> <p:row> <p:button label="Search" id="search"/> <p:separator width="5px"/> </p:row> </p:rows> </p:grid> <p:listbox width="100%" id="resultlist" mold="paging" rows="21" style="font-size: x-small;"> <p:listhead sizable="true"> <p:listheader label="Airline Code" sort="auto" style="font-size: x-small;"/> <p:listheader label="Flightnumber" sort="auto" style="font-size: x-small;"/> <p:listheader label="Flightdate" sort="auto" style="font-size: x-small;"/> <p:listheader label="Destination" sort="auto" style="font-size: x-small;"/> </p:listhead> </p:listbox> </p:window> As you can see, the use attribute of the ZUL page is the link to the SampleController. The SampleController handles and controls the objects. Let's have a short look at the SampleController sample code: public class SampleController extends Window { private Listbox resultlist; private Textbox airlinecode; private Textbox flightnumber; private Datebox flightdate; private Button search; /** * Initialize the page */ public void onCreate() { // Components resultlist = (Listbox) this.getPage().getFellow("query").getFellow("resultlist"); airlinecode = (Textbox) this.getPage().getFellow("query").getFellow("airlinecode"); flightnumber = (Textbox) this.getPage().getFellow("query").getFellow("flightnumber"); flightdate = (Datebox) this.getPage().getFellow("query").getFellow("flightdate"); search = (Button) this.getPage().getFellow("query").getFellow("search"); search.addEventListener("onClick", new EventListener() { public void onEvent(Event event) throws Exception { performSearch(); } }); } /** * Execute the search and fill the list */ private void performSearch() { //(1) List<Flight> flightlist = ((FlightService) SpringUtil.getBean("flightService")). getFlightBySearch(airlinecode.getValue(), flightnumber.getValue(), flightdate.getValue(),""); resultlist.getItems().clear(); for (Flight aFlightlist : flightlist) { // add flights to list } } } /* (1)-shows the integration of the Spring Bean*/ Just for completion the context file for Spring is listed here with the bean that is called. <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="txProxyTemplate" abstract="true" class="org.springframework.transaction. interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"> <ref bean="transactionManager"/> </property> <property name="transactionAttributes"> <props> <prop key="save*">PROPAGATION_REQUIRED</prop> <prop key="add*">PROPAGATION_REQUIRED</prop> <prop key="remove*">PROPAGATION_REQUIRED</prop> </props> </property> </bean> <bean id="flightService" parent="txProxyTemplate"> <property name="target"> <bean class="com.myfoo.services.impl.FlightServiceImpl"> <property name="flightDAO"> <ref bean="flightDao"/> </property> </bean> </property> </bean> </beans> In short we have learned how to use Spring with ZK and about the configurations. We have seen that the integration is quite smooth and also powerful.
Read more
  • 0
  • 0
  • 2521

article-image-sakai-web-services-connecting-enterprise-part-2
Packt
20 Oct 2009
14 min read
Save for later

Sakai Web Services: Connecting to the Enterprise (Part 2)

Packt
20 Oct 2009
14 min read
Sakai and SOAP Sakai SOAP web services piggyback on top of the Apache Axis project. Creating basic Sakai web services is programmer-friendly because Apache Axis removes many of the hard chores. All you have to do is create a Java class in a text file under the /web-apps/sakai-axis directory and any public method is automatically compiled into a service with a WSDL file automatically generated for it, ready for discovery by the client program. The compilation of the web service occurs after creation or modification and is triggered by the next incoming request. What is helpful is that when you make a typo or other mistake, the server displays the compilation error as a web page at the URL of the broken service, as shown in the next screen grab. Notice that the line number and type of error are included. The combination of text processing with a rich set of services to call on, plus the fact that it is not necessary to restart the server every time you compile, makes for rapid development cycles. My first web service To create your first web service, you can add the file /web-apps/sakai-axis/MyTest.jws with the following contents to a running demonstration instance of Sakai: public class MyTest{ public String YouSaid(String message){ return "You said: "+message; }} Then, typing in http://localhost:8080/sakai-axis/MyTest.jws?wsdl will return a corresponding WSDL file similar to the figure below. Notice that it would take a human perhaps 30 minutes to generate the file and the computer took milliseconds. My first client For the programmers among you, the following piece of Perl code consumes the service: #!/usr/bin/perluse SOAP::Lite;my $host='http://localhost:8080';my $soap = SOAP::Lite -> proxy("$host/sakai-axis/MyTest.jws?wsdl");my $result =$soap->YouSaid("WHAT!");print $result->result()."nn"; The returned result is: You said: WHAT! The SOAP Lite module interprets the WSDL file and after that, you can name the web service method directly in the code with the correct number of parameters. This feature results in code that is much more readable and thus maintainable. Changing the variable $host changes the server location. Changing the service and method requires the little nudge of modifying lines 4 and 5. A more realistic client example Sakai web services will not let you perform any action without fulfilling two prerequisites: the first is you need to set the property webservices.allowlogin=true in sakai/sakai.properties, and the second is that the client code needs to obtain a session in the form of a returned random string from a login service, and then use this string as part of any calls you make to other services. If the client code tries to perform any action without logging in, the server returns an error message. The login service requires a username and password and it is very important to note that in production, you are expected to run the client code over an SSL/TLS connection. The following piece of Perl code gets a session ID and then uses it as part of a second web service call to the addNewUser method, which, as you would expect from the name, then creates a new user in Sakai. #!/usr/bin/perluse SOAP::Lite;my $host='http://localhost:8080';my $soap = SOAP::Lite -> proxy("$host/sakai-axis/SakaiLogin.jws?wsdl"); my $result =$soap->login("admin","admin"); my $sessionid=$result->result();$soap = SOAP::Lite -> proxy("$host/sakai-axis/SakaiScript.jws?wsdl"); $soap->addNewUser( $sessionid, 'alanberg', 'Alan', 'Berg', 'berg@xx.nl', '', 'useruser'); if ($result->fault) {print "Error";} else { print "Successn";} Even if you find the Perl code unreadable, the point of the example is to show how only few lines of coding are required for an enterprise to hook into Sakai. Entity Broker Over time, more and more tools and services are included with Sakai. Therefore, there is an ever-expanding set of data, such as courses, users, polls, forums, grade books, assessments, and new data structures, available for integration. It would be handy indeed if instead of needing to write custom web services per new entity, a tool programmer could call a service, write, and register his or her data for exposure. The kernel would then become responsible for the end delivery and the RESTful web services. Because the programmer does not have to deal as much with the details as before the services existed, the structure reduces the duplication of code and effort and increases maintainability, quality, and scalability, and generally eases the programmer's burden. Further, if by default, the entities are exposed as MIME types HTML, .JSON, .XML, you can write rich web-based applications and widget sets that consume the .JSON and .XML formats from the data within Sakai. The Entity Broker is one such service that allows code to find and get at important data in Sakai and easily manipulate that data from within Java objects. To accommodate the ever-changing set of requirements, the data needs to have some uniform parts to it, such as an ID and an associated URL, and it needs to have the ability to register its existence to a central service. If the data has this kind of a structure, it is called an entity, the original technical details of which you can find in the source code under /reference/docs/architecture/sakai_entity.doc. You can find the Java-specific details of the Entity Broker on Confluence (http://confluence.sakaiproject.org/confluence/display/SAKDEV/Entity+Provider+and+Broker). Unless you are a hardcore Sakai kernel programmer, it really is not important to understand the hidden and subtle details. You just need to know how to find out which services exist and how to do business with those services. Finding descriptions of services For the demonstration instance, the Entity Broker services exist under the /direct URL space. To view a human-readable description of all the services, visit http://localhost:8080/direct/desc. The following figure is the description of services available on one of the Sakai QA servers. To zoom into the description of the user service, use the following demonstration URL: http://localhost:8080/direct/user/describe. On different tag versions of Sakai, different services exist. However, every available entity is described by the same URL structure: http://hostname:port/direct/entity_prefix/describe. It is helpful to read the specific description page for each entity, as Entity Broker empowers the programmer to add custom actions. The describe page next is for the user entity. Notice that custom actions currently exist and the server returns data in either XML or in the JSON format. Before logging on to the demonstration instance of Sakai, first visit the URL http://localhost:8080/direct/user/current. Notice that the returned HTML page tells you in a 400 HTTP status error message that there is no current user to get user information about. This makes sense, as you have not logged in. After you log in and revisit the page, the server still does not return the user information. Instead, an error occurs, as HTML is not one of the supported return formats for this entity. The JSON format is, and to obtain your current information in JSON format, simply visit: http://localhost:8080/direct/user/current.json Authenticating At this point in the section, if you have everything set up properly to run TCPMON and watch the request and responses generated, then running the example code mentioned next will allow you to see how REST works in practice. For a client-side application to create a new user, it must first obtain a session via a post to the URL http://localhost:8080/direct/session/new with the variables _username and _password set, as described in http://localhost:8080/direct/session/describe. The server returns the session ID in the form of one of the header values, EntityId, which the script then passes on in any sent requests. You can also pass the sessionId as sakai.session=sessionId as a header or in the URL. You can also use a cookie with the same values included. To create a user, the client application will need to post to the user service with at minimum the eid (Enterprise ID) variable set. Note that the user/describe URL explains which name and value pairs are valid. A client-side coding example For the programming-inclined, I include the following listing that creates a session as user admin, with the password admin, and then creates a user in Sakai with eid=its_alive, firstName=The and lastName=Monster. For the sake of brevity, there is no programmatic error checking. #!/usr/bin/perl -wuse strict;use LWP::UserAgent;use HTTP::Request::Common;my $host='http://localhost:8080';my $credential = "_username=admin&_password=admin";my $user='eid=its_alive&firstName=The&lastName=Monster';my $userAgent = LWP::UserAgent->new();my $response = $userAgent->request(POST "$host/direct/session/new",Content_Type => 'application/x-www-form-urlencoded', Content => $credential);my $entityid= $response->header('EntityId');print "Session: $host/direct/session/$entityidn";$response = $userAgent->request(POST "$host/direct/user/new",Content_Type => 'application/x-www-form-urlencoded', Content => $user);$entityid= $response->header('EntityId');print "User [json format]: $host/direct/user/$entityid.jsonn";print "User [XML format]: $host/direct/user/$entityid.xmln"; On running, the output of the script should look similar to the following: Session: http://localhost:8080/direct/session/770588c7-9a58-46f6-8d47-7c92cab93759User [json format]: http://localhost:8080/direct/user/c9ab941f-3fac-4827-ad00-c4f98cf9ad5e.jsonUser [XML format]: http://localhost:8080/direct/user/c9ab941f-3fac-4827-ad00-c4f98cf9ad5e.xml Once you have written one client script, any new scripts are going to be quite similar. Expect an ever-expanding set of client scripts to be included in the contrib section, waiting for new organizations to pick them up. Interview with Entity Broker author Aaron Zeckoski Who is Aaron Zeckoski and what is his relationship with Sakai? I am a developer and Senior Research Engineer for CARET (Centre for Applied Research in Educational Technologies), University of Cambridge. I am responsible for webapp and service development. I have worked in academic computing for about seven years, maintaining development documentation for Sakai and running training for Sakai developers. I am an inaugural Sakai Fellow and test-driven development advocate, DSpace and Sakai committer. Can you tell us a little bit about the functionality you have been involved in coding into Sakai in general? Many bug fixes and patches for various boring things, Integration works at various universities. Development tools like the Sakai App Builder, ReflectUtils, and GenericDAO. Tools like Evaluation and BlogWow. Data feeds for the UX project. What was your motivation for writing Entity Broker? I needed a way to generate clean URLs into Sakai tools and wanted to make Sakai development and integration with core services easier for the average developer. Further, I wanted a more standard way to handle REST and data input and output in Sakai. I wanted to make external (non-Java) Sakai development easier. Why did you choose to use RESTful services over SOAP services? REST is easier for the average developer to understand and it integrates and works with anything without much effort. It is also much easier to use with things like Javascript/AJAX. Have you any future plans for Entity Broker Add more support for standards (OpenSearch 1.1 URL support was just added) and output formats (RSS, ATOM are on the radar), integration with GWT, make it more modular so it can be used in projects like K2 and DSpace 2. WSRP Portals such as uPortal (http://www.uportal.org) aggregate information from various systems into channels that are part of one view for the user. A typical university may include an accumulation of the newest emails, RSS feeds for up and coming events, and links into important systems such as Sakai and the library systems. An institute can enforce a single corporate look and feel through a portal and empower the end user to transverse efficiently through their most current personalized information. In the Java world, programmers can package channels into little applications that interact in a standard way with the portal system. These standard packages are called portlets and the interactions are standardized via JSR-168 (http://jcp.org/aboutJava/communityprocess/review/jsr168/). This standardization allows the portlets to be shared between different commercial and non-commercial portals and enables organizations to avoid locking in to a particular vendor's solution. The issue with JSR-168 portlets is that the standardization constrains the range of events the portlet can react to and consequently makes the user experience less rich. Portlets reside on the portal and, traditionally, get their own external data from RSS feeds or under the water via web services. Sakai is thoroughly RSS enabled. For example, visit the main page of your demonstration server with the URL http://localhost:8080/portal/rss and you will see an RSS-rendered version of the main page. After logging in and visiting the page again, you will get to see more details. For a PDA-compliant page, visit http://localhost:8080/portal/pda. Having all the portlet code on the portal system makes for a lot of code in one place and this is a serious risk for later trouble in terms of performance, code duplication, maintainability, and connecting to external data sources consistently. The web services for Remote Portlets WSRP (http://oasis-open.org/committee/wsrp) service allows a Portal to call WSRP-enabled portlets remotely directly from the portal via web services. On the portal side, all you would need now is a connector that an administrator can then configure to target a specific service. Building a viable Portal system has knock-on effects on the background systems. If users hit the Portal heavily, and potentially the whole of an organizations population, then also expect a considerable increase in usage on the secondary systems. The deploying organization needs to preemptively strengthen legacy systems. Further, end users naturally expect to safely follow links from the various feeds directly into the associated background application. End users do not expect to have to log in more than once and only through the portal. If enacted, Single Sign On through mechanisms such as CAS (http://www.ja-sig.org/products/cas/) or Shibboleth (http://shibboleth.internet2.edu/) is viable. Uniform provisioning of user accounts across the full spectrum of linked-to applications is also a concern. For Sakai, it makes sense to expose to a portal user a list of what is new in the user's courses, schedules, the Message of the Day, and other facets of the daily interaction between learners and Sakai. Whenever possible, it is a good idea for system integrators to use current standards to do so. Activating the services within Sakai requires downloading and installing an extra web application (Servlet) that runs within a specific Sakai instance and delivers the WSRP producer services. The location of the most up-to-date README is https://source.sakaiproject.org/svn/wsrp/trunk/producer/README.txt. The code is based on the WSRP4J framework http://portals.apache.org/wsrp4j. As the code is not included as part of the enterprise core tool set, your organization will have to fully test any significant deployments. In summary to this section, there is code available to connect a Portal to Sakai via WSRP-based web services. However, you need to test the code before you deploy it in production. Summary By placing a text file with a few lines of Java in the right location in Sakai, a programmer can create new web services rapidly. Many client-side libraries remove the need to understand the underlying complexities of the protocols involved. The Entity Broker exposes managed data (entities) within Sakai, such as the representation of users and sites by RESTful web services. You can discover currently available services by visiting http://host/direct. It is possible to connect Sakai to Portal systems via the WSRP standard.
Read more
  • 0
  • 0
  • 2462
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €18.99/month. Cancel anytime
article-image-customizing-page-management-liferay-portal-52-systems-development
Packt
20 Oct 2009
5 min read
Save for later

Customizing Page Management in Liferay Portal 5.2 Systems Development

Packt
20 Oct 2009
5 min read
Customizing page management with more features The Ext Manage Pages portlet not only clones the out of the box Manage Pages portlet, but it also extends the model and service — supporting customized data, for example, Keywords. We can make these Keywords localized too.   Adding localized feature Liferay portal is designed to handle as many languages as you want to support. By default, it supports up to 22 languages. When a page is loading, the portal will detect the language, pull up the corresponding language file, and display the text in the correct language. We want the Keywords to be localized too. For example, the default language is English (United States) and the localized language is Deutsch (Deutschland). Thus, you have the ability to enter not only the Name and HTML Title in German, but also the Keywords in German. As shown in the following screenshot, when you change the language of the page in German using the language portlet, you will see the entire web site changed to German, including the portlet title and input fields. For example, the title of the portlet now has the Ext Seiteneinstellungen value and the Keywords now become Schlüsselwörter. How do we implement this feature? In other words, how do we customize the language display in the page management? Let's add the localized feature for the Ext Manage Pages portlet. Extending model for locale First of all, we need to extend the model and to implement that model in order to support the localized feature. For the ExtLayout model, let's add the locale method first. Locate the ExtLayout.java file from the com.ext.portlet.layout.model package in the /ext/ext-service/src folder, and open it. Add the following lines before the line } in ExtLayout.java and save it: public String getKeywords(Locale locale);public String getKeywords(String localeLanguageId);public String getKeywords(Locale locale, boolean useDefault);public String getKeywords(String localeLanguageId, boolean useDefault);public void setKeywords(String keywords, Locale locale); As shown in the code above, it adds getting and setting methods for the Keywords field with locale features. Now let's add the implementation for the ExtLayout model: Locate the ExtLayoutImpl.java file from the com.ext.portlet.layout.model.impl package in the /ext/ext-impl/src folder and open it. Add the following lines before the last } in ExtLayoutImpl.java file and save it: public String getKeywords(Locale locale) { String localeLanguageId = LocaleUtil.toLanguageId(locale); return getKeywords(localeLanguageId);}public String getKeywords(String localeLanguageId) { return LocalizationUtil.getLocalization(getKeywords(), localeLanguageId);}public String getKeywords(Locale locale, boolean useDefault) { String localeLanguageId = LocaleUtil.toLanguageId(locale); return getKeywords(localeLanguageId, useDefault);}public String getKeywords(String localeLanguageId, boolean useDefault) { return LocalizationUtil.getLocalization( getKeywords(), localeLanguageId, useDefault);}public void setKeywords(String keywords, Locale locale) { String localeLanguageId = LocaleUtil.toLanguageId(locale); if (Validator.isNotNull(keywords)) { setKeywords(LocalizationUtil.updateLocalization( getKeywords(), "keywords", keywords, localeLanguageId)); } else { setKeywords(LocalizationUtil.removeLocalization( getKeywords(), "keywords", localeLanguageId)); }} As shown in the code above, it adds implementation for get and set methods of the ExtLayout model. Customizing language properties Language files have locale-specific definitions. By default, Language.properties (at /portal/portal-impl/src/content) contains English phrase variations further defined for United States, while Language_de.properties (at /portal/portal-impl/src/content) contains German phrase variations further defined for Germany. In Ext, Language-ext.properties (available at /ext/ext-impl/src/content) contains English phrase variations further defined for United States, while Language-ext_de.properties (should be available at /ext/ext-impl/src/content) contains German phrase variations further defined for Germany. First, let's add a message in Language-ext.properties, by using the following steps: Locate the Language-ext.properties file in the /ext/ext-impl/src/content folder and open it. Add the following line after the line view-reports=View Reports for Books and save it. keywords=Keywords This code specifies the keywords message key with a Keywords value in English: Then we need to add German language feature in Language-ext_de.properties as follows: Create a language file Language-ext_de.properties in the /ext/ext-impl/src/content folder and open it. Add the following lines at the beginning and save it: ## Portlet namesjavax.portlet.title.EXT_1=Berichtejavax.portlet.title.jsp_portlet=JSP Portletjavax.portlet.title.book_reports=Berichte für das Buchjavax.portlet.title.extLayoutManagement=Ext Seiteneinstellungenjavax.portlet.title.extCommunities=Ext Communities## Messagesview-reports=Ansicht-Berichte für Bücherkeywords=Schlüsselwörter## Category titlescategory.book=Buch## Model resourcesmodel.resource.com.ext.portlet.reports.model.ReportsEntry= Buch ## Action namesaction.ADD_BOOK=Fügen Sie Buch hinzu As shown in the code above, it specifies the same keys as that of Language-ext.properties. But all the keys' values were specified in German instead of English. For example, the message keywords has a Schlüsselwörter value in German. In addition, you can set German as the default language and Germany as the default country if it is required. Here are the simple steps to do so: Locate the system-ext.properties file in the /ext/ext-impl/src folder and open it. Add the following lines at the end of system-ext.properties and save it: user.country=DEuser.language=de The code above sets the default locale — the language German (Deutsch) and the country Germany (Deutschland). In general, there are many language files, for example Language-ext.properties and Language-ext_de.properties, and some language files would overwrite others in runtime loading. For example, Languageext_de.properties will overwrite Language-ext.properties when the language is set as German. These are the three simple rules which indicate the priorities of these language files: The ext versions take precedence over the non-ext versions. The language-specific versions, for example _de, take precedence over the non language-specific versions. The location-specific versions, such as -ext_de, take precedence over the non location-specific versions. For instance, the following is a ranking from bottom to top for the German language: Language-ext_de.properties Language_de.properties Language-ext.properties Language.properties
Read more
  • 0
  • 0
  • 2315

article-image-data-migration-scenarios-sap-business-one-application-part-1
Packt
20 Oct 2009
25 min read
Save for later

Data Migration Scenarios in SAP Business ONE Application- part 1

Packt
20 Oct 2009
25 min read
Just recently, I found myself in a data migration project that served as an eye-opener. Our team had to migrate a customer system that utilized Act! and Peachtree. Both systems are not very famous for having good accessibility to their data. In fact, Peachtree is a non-SQL database that does not enforce data consistency. Act! also uses a proprietary table system that is based on a non-SQL database. The general migration logic was rather straightforward. However, our team found that the migration and consolidation of data into the new system posed multiple challenges, not only on the technical front, but also for the customer when it came to verifying the data. We used the on-the-edge tool xFusion Studio for data migration. This tool allows migrating and synchronizing data by using simple and advanced SQL data messaging techniques. The xFusion Studio tool has a graphical representation of how the data flows from the source to the target. When I looked at one section of this graphical representation, I started humming the song Welcome to the Jungle. Take a look at the following screenshot and find out why Guns and Roses may have provided the soundtrack for this data migration project: What we learned from the above screenshot is quite obvious and I have dedicated this article to helping you overcome these potential issues. Keep it simple and focus on information rather than data. You know that just by having more data does not always mean you’ve added more information. Sometimes, it just means a data jungle has been created. Making the right decisions at key milestones during the migration can keep the project simple and guarantee the success. Your goal should be to consolidate the islands of data into a more efficient and consistent database that provides real-time information. What you will learn about data migration In order to accomplish the task of migrating data from different sources into SAP Business ONE application, a strategy must be designed that addresses the individual needs of the project at hand. The data migration strategy uses proven processes and templates. The data migration itself can be managed as a mini project depending on the complexity. During the course of this article, the following key topics will be covered. The goal is to help you make crucial decisions, which will keep a project simple and manageable: Position the data migration tasks in the project plan – We will start by positioning the data migration tasks in the project plan. I will further define the required tasks that you need to complete as a part of the data migration. Data types and scenarios – With the general project plan structure in place, it is time to cover the common terms related to data migration. I will introduce you to the main aspects, such as master data and transactional data, as well as the impact they have on the complexity of data migration. SAP tools available for migration – During the course of our case study, I will introduce you to the data migration tools that come with SAP. However, there are also more advanced tools for complex migrations. You will learn about the main player in this area and how to use it. Process of migration – To avoid problems and guarantee success, the data migration project must follow a proven procedure. We will update the project plan to include the procedure and will also use the process during our case study. Making decisions about what data to bring – I mentioned that it is important to focus on information versus data. With the knowledge of the right tools and procedures, it is a good time to summarize the primary known issues and explain how to tackle them. The project plan We are still progressing in Phase 2 – Analysis and Design. The data migration is positioned in the Solution Architecture section and is called Review Data Conversion Needs (Amount and Type of Data). A thorough evaluation of the data conversion needs will also cover the next task in the project plan called Review Integration Points with any 3rd Party Solution. As you can see, the data migration task stands as a small task in the project plan. But as mentioned earlier, it can wind up being a large project depending on the number and size of data sources that need to be migrated. To honor this, we will add some more details to this task. As the task name suggests, we must review data conversion needs and identify the amount and type of data. This simple task must be structured in phases, just like the entire project that is structured in phases. Therefore, data migration needs to go through the following phases to be successful: 1. Design - Identify all of the Data Sources 2. Extraction of data into Excel or SQL for review and consistency 3. Review of Data and Verification(Via Customer Feedback) 4. Load into SAP System and Verification Note that the validation process and the consequential load could be iterative processes. For example, if the validated data has many issues, it only makes sense to perform a load into SAP if an additional verification takes place before the load. You only want to load data into an SAP system for testing if you know the quality of the records going to be loaded is good. Therefore, new phases were added in the project plan (seen below). Please do this in your project too based on the actual complexity and the number of data sources you have. A thorough look at the tasks above will be provided when we talk about the process of migration. Before we do that, the basic terms related to data migration will be covered. Data sources—where is my data There is a great variety in the potential types data sources. We will now identify the most common sources and explain their key characteristics. However, if there is a source that is not mentioned here, you can still migrate the data easily by transitioning it into one of the following formats. Microsoft Excel and text data migration The most common format for data migration is Excel, or text-based files. Text-based files are formatted using commas or tabs as field separators. When a comma is used as a field separator, the file format is referred to as Comma Separated Values (CSV). Most of the migration templates and strategies are based on Excel files that have specific columns where you can manually enter data, or copy and paste larger chunks. Therefore, if there is any way for you to extract data from your current system and present it in Excel, you have already done a great deal of data migration work. Microsoft Access An Access database is essentially an Excel sheet on a larger scale with added data consistency capability. It is a good idea to consider extracting Access tables to Excel in order to prepare for data migration. SQL If you have very large sets of data, then instead of using Excel, we usually employ an SQL database. The database then has a set of tables instead of Excel sheets. Using SQL tables, we can create SQL statements that can verify data and analyze results sets. Please note that you can use any SQL database, such as Microsoft SQL Server, Oracle, IBM DB, and so on. SaaS (Netsuite, Salesforce) SaaS stands for Software as a Service. Essentially, it means you can use software functionality based on a subscription. However, you don't own the solution. All of the hardware and software is installed at the service center, so you don't need to worry about hardware and software maintenance. However, keep in mind that these services don't allow you to manage the service packs according to your requirements. You need to adjust your business to the schedule of the SaaS company. If you are migrating from a modern SaaS solution, such as Salesforce or Netsuite, you will probably know that the data is not at your site, but rather stored at your solution hosting provider. Getting the data out to migrate to another solution may be done by obtaining reports, which could then be saved in an Excel format. Other legacy data The term legacy data is often mentioned when evaluating larger old systems. Legacy data basically comprises a large set of data that a company is using on mostly obsolete systems. AS/400 or Mainframe The IBM AS/400 is a good example of a legacy data source. Experts who are capable of extracting data from these systems are highly sought after, and so the budget must be on a higher scale. AS/400 data can often be extracted into a text or an Excel format. However, the data may come without headings. The headings are usually documented in a file that describes the data. You need to make sure that you get the file definitions, without which the pure text files may be meaningless. In addition, the media format is worth considering. An older AS/400 system may utilize a backup tape format which is not available on your Intel server. Peachtree, QuickBooks, and Act! Another potential source for data migration may be a smaller PC-based system, such as Peachtree, QuickBooks, or Act!. These systems have a different data format, and are based on non-SQL databases. This means the data cannot be accessed via SQL. In order to extract data from those systems, the proprietary API must be used. For example, if Peachtree displays data in the applications forms, it uses the program logic to put the pieces together from different text files. Getting data out from these types of systems is difficult and sometimes impossible. It is recommended to employ the relevant API to access the data in a structured way. You may want to run reports and export the results to text or Excel. Data classification in SAP Business ONE There are two main groups of data that we will migrate to the SAP Business ONE application: master data and transaction data. Master data Master data is the basic information that SAP Business ONE uses to record transactions (for example, business partner information). In addition, information about your products, such as items, finished goods, and raw materials are considered master data. Master data should always be migrated if possible. It can easily be verified and structured in an Excel or SQL format. For example, the data could be displayed using Excel sheets. You can then quickly verify that the data is showing up in the correct columns. In addition, you can see if the data is broken down into its required components. For example, each Excel column should represent a target field in SAP Business ONE. You should avoid having a single column in Excel that provides data for more than one target in SAP Business ONE. Transaction data Transaction data are proposals, orders, invoices, deliveries, and other similar information that comprise a combination of master data to create a unique business document. Customers often will want to migrate historical transactions from older systems. However, the consequences of doing this may have a landslide effect. For example, inventory is valuated based on specific settings in the finance section of a system. If these settings are not identical in the new system, transactions may look different in the old and the new system. This makes the migration very risky as the data verification becomes difficult on the customer side. I recommend making historical transactions available via a reporting database. For example, often, sales history must be available when migrating data. You can create a reporting database that provides sales history information. The user can use this data via reports within the SAP Business ONE application. Therefore, closed transactions should be migrated via a reporting database . Closed transactions are all of the business-related activities that were fully completed in the old system. Open transactions, on the other hand, are all of the business-related activities that are currently not completed. It makes sense that the open transactions be migrated directly to SAP, and not to a history database because they will be completed within the new SAP system. As a result of the data migration, you would be able to access sales history information from within SAP by accessing a reporting database. Open transactions will be completed within SAP, and then consequently lead to new transactions in SAP. Create a history database for sales history and manually enter open transactions. SAP DI-API Now that we know the main data types for an SAP migration, and the most common sources, we can take a brief look at the way the data is inserted into the SAP system. Based on the SAP guidelines, you are not allowed to insert data directly in the underlying SQL tables. The reason for that is that it can cause inconsistencies. When SAP works with the database, multiple tables are often updated. If you manually update a table to insert data, there is a good chance that another table has a link that also requires updating. Therefore, unless you know the exact table structure for the data you are trying to update, don't mess with the SAP SQL tables. If you carefully read this and understand the table structure, you will now know that there may be situations where you decide to access the tables directly. If you decide to insert data directly into the SAP database tables, you run the risk of losing your warranty. Migration scenarios and key decisions Data migration not only takes place as a part of a new SAP implementation, but also if you have a running system and you want to import leads or a list of new items. Therefore, it is a good idea to learn about the scenarios that you may come across and be able to select the right migration and integration tools. As outlined before, data can be divided into two groups: master data and transaction data. It is important that you separate the two, and structure each data migration accordingly. Master data is an essential component for manifesting transactions. Therefore, even if you need to bring over transactional data, the master data must already be in place. Always start with the master data alongside a verification procedure, and then continue with the relevant transaction data. Let’s now briefly look at the most common situations where you may require the evaluation of potential data migration options. New company (start-up) In this setup, you may not have extensive amounts of existing data to migrate. However, you may want to bring over lead lists or lists of items. During the course of this article, we will import a list of leads into SAP using the Excel Import functionality. Many new companies require the capability to easily import data into SAP. As you already know by now, the import of leads and item information will be considered as importing master data. Working with this master data by entering sales orders and so forth, would constitute transaction data. Transaction data is considered closed if all of the relevant actions are performed. For example, a sales order is considered closed if the items are delivered, invoiced, and paid for. If the chain of events is not complete, the transaction is open. Islands of data scenario This is the classic situation for an SAP implementation. You will first need to identify the available data sources and their formats. Then, you select the master data you want to bring over. With multiple islands of data, an SAP master record may result from more than one source. A business partner record may come, in part, from an existing accounting system, such as QuickBooks or Peachtree. Whereas other parts may come from a CRM system, such as Act!. For example, the billing information may be retrieved from the finance system and the relevant lead and sales information, such as specific contacts and notes, may come from the CRM system. In such a case, you need to merge this information into a new consistent master record in SAP. For this situation, first manually put the pieces together. Once the manual process works, you can attempt to automate the process. Don't try to directly import all of the data. You should always establish an intermediary level that allows for data verification. Only then import the data into SAP. For example, if you have QuickBooks and Act!, first merge the information into Excel for verification, and then import it into SAP. If the amount of data is large, you can also establish an SQL database. In that case, the Excel sheets would be replaced by SQL tables. IBM legacy data migration The migration of IBM legacy data is potentially the most challenging because the IBM systems are not directly compatible with Windows-based systems. Therefore, almost naturally, you will establish a text-based, or an Excel-formatted, representation of the IBM data. You can then proceed with verifying the information. SQL migration The easiest migration type is obviously the one where all of the data is already structured and consistent. However, you will not always have documentation of the table structure where the data resides. In this case, you need to create queries against the SQL tables to verify the data. The queries can then be saved as views. The views you create should always represent a consistent set of information that you can migrate. For example, if you have one table with address information, and another table with customer ID fields, you can create a view that consolidates this information into a single consistent set. Process of migration for your project I briefly touched upon the most common data migration scenarios so you can get a feel for the process. As you can see, whatever the source of data is, we always attempt to create an intermediary platform that allows the data to be verified. This intermediary platform is most commonly Excel or an SQL database. The process of data migration has the following subtasks: Identify available data sources Structure data into master data and transaction data Establish an intermediary platform with Excel or SQL Verify data Match data columns with Excel templates Run migration based on templates and verify data Based on this procedure, I have added more detail to the project plan. As you can see in this example, based on the required level of detail, we can make adjustments to the project plan to address the requirements: SAP standard import features Let's take a look at the available data exchange features in SAP. SAP provides two main tools for data migration. The fi rst option is to use the available menu in the SAP Business ONE client interface to exchange data. The other option is to use the Data Transfer Workbench (DTW). Standard import/export features— walk-through You can reach the Import from Excel form via Administration | Data Import/Export. As you can see in the following screenshot on the right top section of the form, the type of import is a drop-down selection. The options are BP and Items. In the screenshot, we have selected BP, which allows business partner information to be imported. There are drop-down fields that you can select based on the data you want to import. However, keep in mind that certain fields are mandatory, such as the BP Code field, whereas others are optional. The fields you select are associated with a column as you can see here: If you want to find out if a field is mandatory or not, simply open SAP and attempt to enter the data directly in the relevant SAP form. For example, if you are trying to import business partner information, enter the fields you want to import and see if the record can be saved. If you are missing any mandatory fields, SAP will provide an error message. You can modify the data that you are planning to import based on that. When you click on the OK button in the Import from Excel form (seen above), the Excel sheet with all of the data needs to be selected. In the following screenshot, you can see how the Excel sheet in our example looks. For example, column A has all of the BP Codes. This is in line with the mapping of columns to fields that we can see on the Import from Excel form. Please note that the file we select must be in a .txt format. For this example, I used the Save As feature in Excel (seen in the following screenshot) to save the file in the Text MS-DOS (*.txt) format. I was then able to select the BP Migration.txt file. This is actually a good thing because it points to the fact that you can use any application that can save data in the .txt format as the data source. The following screenshot shows the Save As screen: I imported the file and a success message confirms that the records were imported into SAP: A subsequent check in SAP confirms that the BP records that I had in the text file are now available in SAP: In the example, we only used two records. It is recommended to start out with a limited number of records to verify that the import is working. Therefore, you may start by reducing your import file to five records. This has the advantage of the import not taking a long time and you can immediately verify the result. See the following screenshot: Sometimes, it is not clear what kind of information SAP expects when importing. For example, at first Lead, Customer, Vendor were used in Column C to indicate the type of BP that was to be imported. However, this resulted in an error message upon completion of the import. Therefore, system information was activated to check what information SAP requires for the BP Type representation. As you can see in the screenshot of the Excel sheet you get when you click on the OK button in the Import from Excel form, the BP Type information is indicated by only one letter using L, C, or V. In the example screenshot above, you can clearly see L in the lower left section. The same thing is done for Country in the Addresses section. You can try that by navigating to Administration | Sales | Countries, and then hovering over the country you will be importing. In my example, USA was internally represented by SAP as US. It is a minor issue. However, when importing data, all of these issues need to be addressed. Please note that the file you are trying to import should not be open in Excel at the same time, as this may trigger an error. The Excel or text file does not have a header with a description of the data. Standard import/export features for your own project SAP’s standard import functionality for business partners and items is very straightforward. For your own project, you can prepare an Excel sheet for business partners and items. If you need to import BP or item information from another system, you can get this done quickly. If you get an error during the import process, try to manually enter the data in SAP. In addition, you can use the System Information feature to identify how SAP stores information in the database. I recommend you first create an Excel sheet with a maximum of two records to see if the basic information and data format is correct. Once you have this running, you can add all of the data you want to import. Overall, this functionality is a quick way to get your own data into the system. This feature can also be used in case you regularly receive address information. For example, if you have salespeople visiting trade fairs, you can provide them with the Excel sheet that you may have prepared for BP import. The salespeople can directly add their information there. Once they return from the trade fair with the Excel fi les, you can easily import the information into SAP and schedule follow-up activities using the Opportunity Management System. The item import is useful if you work with a vendor who updates his or her price lists and item information on a monthly basis. You can prepare an Excel template where the item information will regularly be entered and you can easily import the updates into SAP. Data Migration Workbench (DTW) The SAP standard import/export features are straightforward, but may not address the full complexity of the data that you need to import. For this situation, you may want to evaluate the SAP Data Migration Workbench (DTW). The functionality of this tool provides a greater level of detail to address the potential data structures that you want to import. To understand the basic concept of the DTW, it is a good idea to look at the different master data sections in SAP as business objects. A business object groups related information together. For example, BP information can have much more detail than what was previously shown in the standard import. The DTW templates and business objects To better understand the business object metaphor, you need to navigate to the DTW directory and evaluate the Templates folder. The templates are organized by business objects. The oBusinessPartners business object is represented by the folder with the same name (seen below). In this folder, you can find Excel template files that can be used to provide information for this type of business object. The following objects are available as Excel templates: BPAccountReceivables BPAddresses BPBankAccounts BPPaymentDates BPPaymentMethods BPWithholdingTax BusinessPartners ContactEmployees Please notice that these templates are Excel .xlt files, which is the Excel template extension. It is a good idea to browse through the list of templates and see the relevant templates. In a nutshell, you essentially add your own data to the templates and use DTW to import the data. Connecting to DTW In order to work with DTW, you need to connect to your SAP system using the DTW interface. The following screenshot shows the parameters I used to connect to the Lemonade Stand database: Once you are connected, a wizard-type interface walks you through the required steps to get started. Look at the next screenshot: The DTW examples and templates There is also an example folder in the DTW installation location on your system. This example folder has information about how to add information to your Excel templates. The following screenshot shows an example for business partner migration. You can see that the Excel template does have a header line on top that explains the content in the particular column. The actual template files also have comments in the header fi le, which provide information about the data format expected, such as String, Date, and so on. See the example in this screenshot: The actual template is empty and you need to add your information as shown here:   DTW for your own project If you realize that the basic import features in SAP are not sufficient, and your requirements are more challenging, evaluate DTW. Think of the data you want to import as business objects where information is logically grouped. If you are able to group your data together, you can modify the Excel templates with your own information. The DTW example folder provides working examples that you can use to get started. Please note that you should establish a test database before you start importing data this way. This is because once new data arrives in SAP, you need to verify the results based on the procedure discussed earlier. In addition, be prepared to fine-tune the import. Often, an import and data verification process takes four attempts of data importing and verification. Summary In this article, we covered the tasks related to data migration. This also included some practical examples for simple data imports related to business partner information and items. In addition, more advanced topics were covered by introducing the SAP DTW (Data Transfer Workbench) and the related aspects to get you started. During the course of this article, we positioned the data migration task in the project plan. The project plan was then fine-tuned with more detail to give some justice to the potential complexity of a data migration project. The data migration tasks established a process, from design to data mapping and verification of the data. Notably, the establishment of an intermediary data platform was recommended for your projects. This will help you verify data at each step of the migration. The key message of keeping it simple will be the basis for every migration project. The data verification task ensures simplicity and the quality of your data. If you have read this article you may be interested to view : Competitive Service and Contract Management in SAP Business ONE Implementation: Part 1 Competitive Service and Contract Management in SAP Business ONE Implementation: Part 2 Data Migration Scenarios in SAP Business ONE Application- part 2
Read more
  • 0
  • 0
  • 11269

article-image-3d-vector-drawing-and-text-papervision3d-part-1
Packt
20 Oct 2009
4 min read
Save for later

3D Vector Drawing and Text with Papervision3D: Part 1

Packt
20 Oct 2009
4 min read
The main part of this article is dedicated to a library called VectorVision that was incorporated into Papervision3D. After discussing the classes of this library, we will take a look at the Lines3D class in the next part that also enables you to draw 3D lines. This class was already a part of Papervision3D before VectorVision was incorporated. VectorVision: 3D vector text and drawing VectorVision is a library written in ActionScript that allows you to render vector graphics in Papervision3D and add a 3D perspective to them. The project started as a separate library that you could download and use as an add-on. However, it was fully integrated in Papervision3D in June 2008. Being able to use vector shapes and text theoretically means that you could draw any kind of vector graphic and give it a 3D perspective. This article will focus on the features that are implemented in Papervision3D: Creating 3D vector text Drawing 3D vector shapes such as lines, circles, and rectangles Keep in mind that 3D letters can be seen as vector shapes too, just like lines, circles, and rectangles. The above distinction is made based on how VectorVision is implemented in Papervision3D. Some classes specifically deal with creating 3D text, whereas others enable you to create vector shapes. Creating a template class for the 3D text examples Because the 3D text examples we are about to see have a lot in common, we will use a template class that looks as follows: package{ import flash.events.Event; import org.papervision3d.materials.special.Letter3DMaterial; import org.papervision3d.typography.Font3D; import org.papervision3d.typography.Text3D; import org.papervision3d.typography.fonts.HelveticaBold; import org.papervision3d.view.BasicView; public class Text3DTemplate extends BasicView { private var material:Letter3DMaterial; private var font3D:Font3D; private var text3D:Text3D; private var easeOut:Number = 0.6; private var reachX:Number = 0.5 private var reachY:Number = 0.5 private var reachZ:Number = 0.5; public function Text3DTemplate() { stage.frameRate = 40; init(); startRendering(); } private function init():void { //code to be added } override protected function onRenderTick(event:Event = null):void { var xDist:Number = mouseX - stage.stageWidth * 0.5; var yDist:Number = mouseY - stage.stageHeight * 0.5; camera.x += (xDist - camera.x * reachX) * easeOut; camera.y += (yDist - camera.y * reachY) * easeOut; camera.z += (-mouseY * 2 - camera.z ) * reachZ; super.onRenderTick(); } }} We added some class properties that are used in the render method, where we added code to move the camera when the mouse moves. Also, we imported four classes and added three class properties that will enable us to create 3D text. How to create and add 3D text Let's see how we can create 3D vector text that looks crisp and clear. The general process of creating and displaying 3D text looks as follows: Create material with Letter3DMaterial. Create a Font3D instance. Create a Text3D instance, passing the text, font, and material to it, and add it to the scene or to another do3D. We will create an example that demonstrates several features of Text3D: Multiline Alignment Outlines All the following code should be added inside the init() method. Before we instantiate the classes that we need in order to display 3D text, we assign a text string to a local variable. var text:String = "Multiline 3D textnwith letter spacing,nline spacing,nand alignment ;-)"; Now, let's create a text material, font, and text. First we instantiate Letter3DMaterial, which resides in the org.papervision3d.materials.special package: material = new Letter3DMaterial(0x000000); The constructor of this class takes two optional parameters:
Read more
  • 0
  • 0
  • 3026

article-image-primitive-data-types-variables-and-operators-object-oriented-javascript
Packt
20 Oct 2009
10 min read
Save for later

Primitive Data Types, Variables, and Operators in Object-Oriented JavaScript

Packt
20 Oct 2009
10 min read
Let's get started. Variables Variables are used to store data. When writing programs, it is convenient to use variables instead of the actual data, as it's much easier to write pi instead of 3.141592653589793 especially when it happens several times inside your program. The data stored in a variable can be changed after it was initially assigned, hence the name "variable". Variables are also useful for storing data that is unknown to the programmer when the code is written, such as the result of later operations. There are two steps required in order to use a variable. You need to: Declare the variable Initialize it, that is, give it a value In order to declare a variable, you use the var statement, like this: var a;var thisIsAVariable;var _and_this_too;var mix12three; For the names of the variables, you can use any combination of letters, numbers, and the underscore character. However, you can't start with a number, which means that this is invalid: var 2three4five; To initialize a variable means to give it a value for the first (initial) time. You have two ways to do so: Declare the variable first, then initialize it, or Declare and initialize with a single statement An example of the latter is: var a = 1; Now the variable named a contains the value 1. You can declare (and optionally initialize) several variables with a single var statement; just separate the declarations with a comma: var v1, v2, v3 = 'hello', v4 = 4, v5; Variables are Case Sensitive Variable names are case-sensitive. You can verify this statement using the Firebug console. Try typing this, pressing Enter after each line: var case_matters = 'lower';var CASE_MATTERS = 'upper';case_mattersCASE_MATTERS To save keystrokes, when you enter the third line, you can only type ca and press the Tab key. The console will auto-complete the variable name to case_matters. Similarly, for the last line—type CA and press Tab. The end result is shown on the following figure. Throughout the rest of this article series, only the code for the examples will be given, instead of a screenshot: >>> var case_matters = 'lower';>>> var CASE_MATTERS = 'upper';>>> case_matters"lower">>> CASE_MATTERS"upper" The three consecutive greater-than signs (>>>) show the code that you type, the rest is the result, as printed in the console. Again, remember that when you see such code examples, you're strongly encouraged to type in the code yourself and experiment tweaking it a little here and there, so that you get a better feeling of how it works exactly. Operators Operators take one or two values (or variables), perform an operation, and return a value. Let's check out a simple example of using an operator, just to clarify the terminology. >>> 1 + 23 In this code: + is the operator The operation is addition The input values are 1 and 2 (the input values are also called operands) The result value is 3 Instead of using the values 1 and 2 directly in the operation, you can use variables. You can also use a variable to store the result of the operation, as the following example demonstrates: >>> var a = 1;>>> var b = 2;>>> a + 12>>> b + 24>>> a + b3>>> var c = a + b;>>> c3 The following table lists the basic arithmetic operators: Operator symbol Operation Example + Addition >>> 1 + 2 3 - Subtraction >>> 99.99 - 11 88.99 * Multiplication >>> 2 * 3 6 / Division >>> 6 / 4 1.5 % Modulo, the reminder of a division >>> 6 % 3 0 >>> 5 % 3 2 It's sometimes useful to test if a number is even or odd. Using the modulo operator it's easy. All odd numbers will return 1 when divided by 2, while all even numbers will return 0. >>> 4 % 2 0 >>> 5 % 2 1 ++ Increment a value by 1 Post-increment is when the input value is incremented after it's returned. >>> var a = 123; var b = a++; >>> b 123 >>> a 124 The opposite is pre-increment; the input value is first incremented by 1 and then returned. >>> var a = 123; var b = ++a; >>> b 124 >>> a 124 -- Decrement a value by 1 Post-decrement >>> var a = 123; var b = a--; >>> b 123 >>> a 122 Pre-decrement >>> var a = 123; var b = --a; >>> b 122 >>> a 122 When you type var a = 1; this is also an operation; it's the simple assignment operation and = is the simple assignment operator. There is also a family of operators that are a combination of an assignment and an arithmetic operator. These are called compound operators. They can make your code more compact. Let's see some of them with examples. >>> var a = 5;>>> a += 3;8 In this example a += 3; is just a shorter way of doing a = a + 3; >>> a -= 3;5 Here a -= 3; is the same as a = a - 3; Similarly: >>> a *= 2;10>>> a /= 5;2>>> a %= 2;0 In addition to the arithmetic and assignment operators discussed above, there are other types of operators, as you'll see later in this article series.   Primitive Data Types Any value that you use is of a certain type. In JavaScript, there are the following primitive data types: Number—this includes floating point numbers as well as integers, for example 1, 100, 3.14. String—any number of characters, for example "a", "one", "one 2 three". Boolean—can be either true or false. Undefined—when you try to access a variable that doesn't exist, you get the special value undefined. The same will happen when you have declared a variable, but not given it a value yet. JavaScript will initialize it behind the scenes, with the value undefined. Null—this is another special data type that can have only one value, the null value. It means no value, an empty value, nothing. The difference with undefined is that if a variable has a value null, it is still defined, it only happens that its value is nothing. You'll see some examples shortly. Any value that doesn't belong to one of the five primitive types listed above is an object. Even null is considered an object, which is a little awkward—having an object (something) that is actually nothing. The data types in JavaScript the data types are either: Primitive (the five types listed above), or Non-primitive (objects) Finding out the Value Type —the typeof Operator If you want to know the data type of a variable or a value, you can use the special typeof operator. This operator returns a string that represents the data type. The return values of using typeof can be one of the following—"number", "string", "boolean", "undefined", "object", or "function". In the next few sections, you'll see typeof in action using examples of each of the five primitive data types. Numbers The simplest number is an integer. If you assign 1 to a variable and then use the typeof operator, it will return the string "number". In the following example you can also see that the second time we set a variable's value, we don't need the var statement. >>> var n = 1;>>> typeof n;"number">>> n = 1234;>>> typeof n;"number" Numbers can also be floating point (decimals): >>> var n2 = 1.23;>>> typeof n;"number" You can call typeof directly on the value, without assigning it to a variable first: >>> typeof 123;"number" Octal and Hexadecimal Numbers When a number starts with a 0, it's considered an octal number. For example, the octal 0377 is the decimal 255. >>> var n3 = 0377;>>> typeof n3;"number">>> n3;255 The last line in the example above prints the decimal representation of the octal value. While you may not be very familiar with octal numbers, you've probably used hexadecimal values to define, for example, colors in CSS stylesheets. In CSS, you have several options to define a color, two of them being: Using decimal values to specify the amount of R (red), G (green) and B (blue) ranging from 0 to 255. For example rgb(0, 0, 0) is black and rgb(255, 0, 0) is red (maximum amount of red and no green or blue). Using hexadecimals, specifying two characters for each R, G and B. For example, #000000 is black and #ff0000 is red. This is because ff is the hexadecimal for 255. In JavaScript, you put 0x before a hexadecimal value (also called hex for short). >>> var n4 = 0x00;>>> typeof n4;"number">>> n4;0>>> var n5 = 0xff;>>> typeof n5;"number">>> n5;255 Exponent Literals 1e1 (can also be written as 1e+1 or 1E1 or 1E+1) represents the number one with one zero after it, or in other words 10. Similarly, 2e+3 means the number 2 with 3 zeros after it, or 2000. >>> 1e110>>> 1e+110>>> 2e+32000>>> typeof 2e+3;"number" 2e+3 means moving the decimal point 3 digits to the right of the number 2. There's also 2e-3 meaning you move the decimal point 3 digits to the left of the number 2. >>> 2e-30.002>>> 123.456E-30.123456>>> typeof 2e-3"number" Infinity There is a special value in JavaScript called Infinity. It represents a number too big for JavaScript to handle. Infinity is indeed a number, as typing typeof Infinity in the console will confirm. You can also quickly check that a number with 308 zeros is ok, but 309 zeros is too much. To be precise, the biggest number JavaScript can handle is 1.7976931348623157e+308 while the smallest is 5e-324. >>> InfinityInfinity>>> typeof Infinity"number">>> 1e309Infinity>>> 1e3081e+308 Dividing by 0 will give you infinity. >>> var a = 6 / 0;>>> aInfinity Infinity is the biggest number (or rather a little bigger than the biggest), but how about the smallest? It's infinity with a minus sign in front of it, minus infinity. >>> var i = -Infinity;>>> i-Infinity>>> typeof i"number" Does this mean you can have something that's exactly twice as big as Infinity—from 0 up to infinity and then from 0 down to minus infinity? Well, this is purely for amusement and there's no practical value to it. When you sum infinity and minus infinity, you don't get 0, but something that is called NaN (Not A Number). >>> Infinity - InfinityNaN>>> -Infinity + InfinityNaN Any other arithmetic operation with Infinity as one of the operands will give you Infinity: >>> Infinity - 20Infinity>>> -Infinity * 3-Infinity>>> Infinity / 2Infinity>>> Infinity - 99999999999999999Infinity NaN What was this NaN you saw in the example above? It turns out that despite its name, "Not A Number", NaN is a special value that is also a number. >>> typeof NaN"number">>> var a = NaN;>>> aNaN You get NaN when you try to perform an operation that assumes numbers but the operation fails. For example, if you try to multiply 10 by the character "f", the result is NaN, because "f" is obviously not a valid operand for a multiplication. >>> var a = 10 * "f";>>> aNaN NaN is contagious, so if you have even only one NaN in your arithmetic operation, the whole result goes down the drain. >>> 1 + 2 + NaNNaN
Read more
  • 0
  • 0
  • 4091
article-image-building-personal-community-liferay-portal-52
Packt
20 Oct 2009
7 min read
Save for later

Building Personal Community in Liferay Portal 5.2

Packt
20 Oct 2009
7 min read
Besides public web sites, it would be nice if we could provide a personal community, that is, My Community, for each registered user. In My Community, users can have a set of public and private pages. Here you can save your favorite games, videos and playlists, and the My Street theme — your background color. As shown in the following screenshot, there is a page my_street with a portlet myStreet, where an end user can sign up, log in, or handle an issue such as Forgot Your Password? o When you click on the SIGN UP button, this My Street portlet will allow the end users to set up his/her account such as creating a nickname, password hint question, password hint answer, your password, and verify password. Further, as the end user, you can set up favorite games, videos and playlists, and background color. You can have your own favorites: number of favorites displayed in My Street (for example, 4, 20, and 35) and My Street theme, (for example, default, Abby Cadabby, Bert, Big Bird, Cookie Monster, and so on). A set of default My Street themes is predefined in /cms_services/images/my_street/ under the folder $CATALINA_HOME/webapps/ and you can choose any one of them at any time. At the same time, you can upload a photo to your own Book Street web page. When logged in, the My Street theme will be applied on Home page, Games landing page, Videos landing page, and Playlist landing page. For example, current user's My Street theme could be applied on Playlist landing page. You may play videos, games, and playlists when you visit the web site www.bookpubstreet.com. When you find your favorite videos, games, and playlists, you can add them into My Street. As shown in the following screenshot, you could be playing a playlist Tickle Time. If you are interested in this playlist, just click on the Add to My Street button. The playlist Tickle Time will be added into My Street as your favorite playlist. In this section, we will show how to implement these features. Customizing user model First, let's customize user model in service.xml in order to support extended user and user preferences. To do so, use the following steps: Create a package com.ext.portlet.user in the /ext/ext-impl/src folder. Create an XML file service.xml in the package com.ext.portlet.comment and open it. Add the following lines in this file and save it: <?xml version="1.0"?><!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 5.2.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_5_2_0.dtd"><service-builder package-path="com.ext.portlet.user"> <namespace>ExtUser</namespace> <entity name="ExtUser" uuid="false" local-service="true" remote-service="true" persistence-class="com.ext.portlet.user.service. persistence. ExtUserPersistenceImpl"> <column name="userId" type="long" primary="true" /> <column name="favorites" type="int" /> <column name="theme" type="String" /> <column name="printable" type="boolean" /> <column name="plainPassword" type="String" /> <column name="creator" type="String" /> <column name="modifier" type="String" /> <column name="created" type="Date" /> <column name="modified" type="Date" /> </entity> <entity name="ExtUserPreference" uuid="false" local-service="true" remote-service="true" persistence-class="com.ext.portlet.user.service. persistence.ExtUserPreferencePersistenceImpl"> <column name="userPreferenceId" type="long" primary="true" /> <column name="userId" type="long"/> <column name="favorite" type="String" /> <column name="favoriteType" type="String" /> <column name="date_" type="Date" /> </entity> <exceptions> <exception>ExtUser</exception> <exception>ExtUserPreference</exception> </exceptions></service-builder> The code above shows the customized user model, including userId associated with USER_ table, favourites, theme, printable, plainPassword, and so on. This code also shows user preferences model, including userPreferenceId, userId, favorite (for example, game/video/playlist UID), favoriteType (for example, game/video/playlist), and the updated date date_. Of course, these models are extensible. You can extend these models for your unique current needs or future requirements. Enter the following tables into database through command prompt: create table ExtUser ( userId bigint not null primary key, creator varchar(125), modifier varchar(125), created datetime null,modified datetime null, favorites smallint, theme varchar(125), plainPassword varchar(125), printable boolean ); create table ExtUserPreference ( usePreferenceId bigint not null primary key, userId bigint not null,favorite varchar(125), favoriteType varchar(125),date_ datetime null ); The preceding code shows the database SQL script for customized user model and user preference model. Similar to XML model ExtUser, this code shows the userId, favorites, theme, plainPassword, and printable table fields. Again, for the XML model ExtUserPreference, this code shows the userId, favorite, favoriteType, date_, and userPreferenceId table fields. Afterwards, we need to build a service with ServiceBuilder. After preparing service.xml, you can build services. To do so, locate the XML file /ext/ext-impl/buildparent.xml, open it, add the following lines between </target> and <target name="build-service-portlet-reports">, and save it: <target name="build-service-portlet-extUser"> <antcall target="build-service"> <param name="service.file" value="src/com/ext/portlet/user/service.xml" /> </antcall></target> When you are ready, just double-click on the Ant target build-service-portletextUser. ServiceBuilder will build related models and services for extUser and extUserPreference.   Building the portlet My Street Similar to how we had built portlet Ext Comment, we can build the portlet My Street as follows: Configure the portlet My Street in both portlet-ext.xml and liferay-portlet-ext.xml files. Set title mapping in the Language-ext.properties file. Add the My Street portlet to the Book category in the liferay-display.xml file. Finally, specify Struts actions and forward paths in the struts-config.xml and tiles-defs.xml files, respectively. Then, we need to create Struts actions as follows: Create a package com.ext.portlet.my_street.action in the folder /ext/ext-impl/src. Add the Java files ViewAction.java, EditUserAction.java, and CreateAccountAction.java in this package. Create a Java file AddUserLocalServiceUtil.java in this package and open it. Add the following methods in AddUserLocalServiceUtil.java and save it: public static ExtUser getUser(long userId){ ExtUser user = null; try{ user = ExtUserLocalServiceUtil.getExtUser(userId); } catch (Exception e){} if(user == null){ user = ExtUserLocalServiceUtil.createExtUser(userId); try{ ExtUserLocalServiceUtil.updateExtUser(user); } catch (Exception e) {} } return user;}public static void deleteUser(long userId) { try{ ExtUserLocalServiceUtil.deleteExtUser(userId); } catch (Exception e){} }public static void updateUser(ActionRequest actionRequest, long userId) { /* ignore details */}public static List<ExtUserPreference> getUserPreferences( long userId, int limit){ /* ignore details */}public static ExtUserPreference addUserPreference( long userId, String favorite, String favoriteType){ /* ignore details */ } As shown in the code above, it shows methods to get ExtUser and ExtUserPreference, to delete ExtUser, and to add and update ExtUser and ExtUserPreference. In addition, we need to provide default values for private page and friendly URL in portal-ext.properties as follows: ext.default_page.my_street.private_page=falseext.default_page.my_street.friend_url=/my_street The code above shows the default private page of my_street as false, default friendly URL of my_street as /my_street. Therefore, you can use VM service to generate a URL in order to add videos, games, and playlists into My Street. Adding Struts view page Now we need to build Struts views pages view.jsp, forget_password.jsp, create_account.jsp, congratulation.jsp, and congrates_uid.jsp. The following are main steps to do so: Create a folder my_street in /ext/ext-web/docroot/html/portlet/ext/. Create JSP file pages view.jsp, view_password.jsp, userQuestions.jsp, edit_account.jsp, create_account.jsp, congratulation.jsp, and congrates_uid.jsp in /ext/ext-web/docroot/html/portlet/ext/my_street/. Note that congrates_uid.jsp is used for the pop-up congratulation of Add to My Street. When you click on the Add to My Street button, a window with congrates_uid.jsp will pop up. userQuestions.jsp is used when the user has forgotten the password of My Street, view_password.jsp is for general view of My Street, congratulation.jsp is used to represent successful information after creating user account, and edit_account.jsp is used to create/update user account.
Read more
  • 0
  • 0
  • 1846

article-image-creating-convincing-images-blender-internal-renderer-part1
Packt
20 Oct 2009
9 min read
Save for later

Creating Convincing Images with Blender Internal Renderer-part1

Packt
20 Oct 2009
9 min read
Throughout the years that have passed since the emergence of Computer Graphics, many aspiring artists tried convincingly to recreate the real world through works of applied art, some of which include oil painting, charcoal painting, matte painting, and even the most basic ones like pastel and/or crayon drawings has already made it through the artistic universe of realism. Albeit the fact that recreating the real world is like reinventing the wheel (which some artists might argue with), it is not an easy task to involve yourself into. It takes a lot of practice, perseverance, and personality to make it through.  But one lesson I have learned from the art world is to consciously and subconsciously observe the world around you. Pay attention to details. Observe how a plant behaves at different environmental conditions, look how a paper's texture is changed when wet, or probably observe how water in a river distorts the underlying objects. These are just some of the things that you can observe around you, and there are a million more or even an infinite number of things you can observe in your lifetime. In the advent of 3D as part of the numerous studies involved in Computer Graphics, a lot of effort has been made into developing tools and applications that emulate real-world environment.  It has become an unstated norm that the more realistic looking an image is, the greater the impact it has on viewers.  That, in turn, is partly true, but the real essence into creating stunning images is to know how it would look beautiful amidst the criteria that are present.  It is not a general requirement that all your images must look hyper realistic, you just have to know and judge how it would look good, after all that's what CG is all about.  And believe it or not, cheating the eye is an essential tool of the trade. In 3D rendering context, there are a number of ways on how to achieve realism in your scenes, but intuitively, the use of external renderers and advanced raytracers does help a lot in the setup and makes the creation process a bit lighter as compared to manually setting up lights, shaders, etc.  But that comes at a rendering time tradeoff.  Unfortunately though, I won't be taking you to the steps on how to setup your scenes for use in external renderers, but instead I'll walk you through the steps on how to achieve slightly similar effects as to that of externals with the use of the native renderer or the internal renderer as some might call it. Hopefully in this short article, I can describe to you numerous ways on how to achieve good-looking and realistic images with some nifty tools, workarounds from within Blender and use the Blender Internal Renderer to achieve these effects. So, let's all get a cup of tea, a comfortable couch, and hop in! On a nutshell, what makes an image look real? Shading, Materials, Shadows, Textures, Transparency, Reflection, Refraction, Highlights, Contrast, Color Balance, DoF, Lens Effects, Geometry (bevels), Subtlety, Environment, Staging, Composite Nodes, Story.. Before Anything Else... Beyond anything that will be discussed here, nothing beats a properly planned and well-imagined scene.  I cannot stress enough how important it is to begin everything with deep and careful planning.  Be it just a ball on a table or a flying scaled bear with a head of a tarsier and legs that of a mouse (?), it is very vital to plan beforehand.  Believe me, once you've planned everything right, you're almost done with your work (which I didn't believe then until I did give it a try).  And of course, with your touch of artistic flavors, a simple scene could just be the grandest one that history has ever seen. This article, by any means, does not technically teach you how to model subjects for your scene nor does it detail the concepts behind lighting (which is an article on its own and probably beyond my knowledge) nor does it teach you “the way” to do things but instead it will lead you through a process by which you will be able to understand your scene better and the concepts behind. I would also be leading you through a series of steps using the same scene we've setup from the beginning and hopefully by the end of the day, we could achieve something that comprises what has been discussed here so far. I have blabbered too much already, haven't I? Yeah.  Ok, on to the real thing. Before you begin the proceeding steps, it is a must (it really really is) to go grab your copy of Blender over at http://www.blender.org/download/get-blender/. The version I used for this tutorial is 2.49a (which should be the latest one being offered at Blender.org [as of this writing]). Scene Setup With every historical and memorable piece, it is a vital part of your 3d journey to setup something on your scene.  I couldn't imagine how a 3D artist could pass on a work with a blank animated scene, hyper minimal I might say. To start off, fire up Blender or your favorite 3D App for that matter and get your scene ready with your models, objects, subjects, or whatever you call them, just get them there inside your scene so we could have something to look at for now, won't we? On the image below (finally, a graphic one!), you could see a sample scene I've setup and a quick render of the said scene. The first image shows my scene with the model, two spheres, a plane, a lamp, and a camera. The second image shows the rendered version.   You'll notice that the image looks dull and lifeless, that is because it lacks the proper visual elements necessary for creating a convincing scene.  The current setup is all set to default, with the objects having no material data but just the premade ones set by Blender and the light’s settings set as they were by default. Shading and Materials To address some issues, we need to identify first what needs to be corrected.  The first thing we might want to do is to add some initial materials to the objects we have just so we could clearly distinguish their roles in the scene and to add some life to the somewhat dry set we have here.  To do so, select one object at a time and add a material. Let’s first select the main character of the scene (or any subject you wish for that matter) by clicking RMB (Right Mouse Button) on the character object, then under the Buttons Window, select Shading (F5), then click the Material Buttons tab, and click on “Add New” to add a new material to our object. Adding a New Material After doing so, more options will show up and this is where the real fun begins. The only thing we’ll be doing for now is to add some basic color and shading to our objects just so we could deviate from the standard gray default.  You’ll notice on the image below that I’ve edited quite a few options.  That’s what we only want for now, let’s leave the other settings as they are and we’ll get back to it as soon as we need to. Character Initial Material Settings   Big Sphere Initial Material Settings Small sphere Initial Material Settings   Ground Initial Material Settings If we do a test render now, here’s how it will look like: Render With Colors Still not so convincing, but somehow we managed to add a level of variety to our scene as compared to the initial render we’ve made.  Looking at the latest render we did, you’ll notice that the character with the two spheres still seem to be floating in space, creating no interaction whatsoever with the ground plane below it. Another thing would be the lack of diffuse color on some parts of the objects, thus creating a pitch black color which, as in this case, doesn’t seem to look good at all since we’re trying to achieve a well-lit, natural environment as much as possible. A quick and easy solution to this issue would be to enable Ambient Occlusion under the World Settings tab. This will tell Blender to create a fake global illumination effect as though you have added a bunch of lights to create the occlusion.  This would be a case similar to adding a dome of spot lights, with each light having a low energy level, creating a subtle AO effect. But for the purposes of this article, we’d be settling for Ambient Occlusion since it is faster to setup and eliminates the additional need for further tweaking. We access the AO (Ambient Occlusion) menu via the World Buttons tab under Shading (F5) menu then clicking the Amb Occ subtab.  Activate Ambient Occlusion then click on Use Falloff and edit the default strength of 1.00 to 0.70, doing so will create further diffusion on darker areas that have been hidden from the occlusion process.  Next would be to click Pixel Cache, I don’t know much technically what this does but what I know from experience is this speeds up the occlusion calculation.   Ambient Occlusion Settings Below, you’ll see the effects of AO as applied to the scene.  Notice the subtle diffusion of color and shadows and the interaction of the objects and the plane ground through the occlusion process.  So far we’ve only used a single lamp as fill light, but later on we’ll be adding further light sources to create a better effect. Render with Ambient Occlusion Whew, we’ve been doing something lately, haven’t we? So far what we did was to create a scene and a render image that will give us a better view of what it’s going to look like.  Next stop, we’ll be creating a base light setup to further create shadows and better looking diffusion. Soon we go!
Read more
  • 0
  • 0
  • 5440

article-image-building-web-service-driven-application-flash-drupal
Packt
20 Oct 2009
6 min read
Save for later

Building a Web Service-driven Application with Flash in Drupal

Packt
20 Oct 2009
6 min read
So, let's take a step-by-step approach on how to accomplish this on the Flash side, which as far as I am concerned, is the fun side! Click here to access all the codes used in this article. Step 1: Creating our Flash application With our chapter2 project open, we can shift our focus to the Actions panel within the Flash IDE. Although working with the Actions panel is great for small applications, we will eventually build onto this Flash application, which might make it impractical to keep all of our ActionScript code within the Actions panel. Because of this, we will first need to create a separate ActionScript file that will serve as our main entry point for our Flash application. This will allow us to easily expand our application and add to the functionality without modifying the Actions panel for every addition we make. Step 2: Creating a main.as ActionScript file For this step, we will simply create an empty file next to our chapter2.fla file called main.as. After you have created this new file, we will then need to reference it within our Actions panel. To do this, we will use the include keyword in ActionScript to include this file as the main entry point for our application. So, shifting our focus back to the chapter2.fla file, we will then place the following code within the Actions panel: include "main.as";stop(); Now that we are referencing the main.as file for any of the ActionScript functionality, we will no longer need to worry about the Actions panel and add any new functionality directly to the main.as file. Now, for the following sections, we will use this main.as file to place all of our ActionScript code that will connect and extract information from our Drupal system, and then populate that information in a TextField that we will create later. So, let's jump right in and write some code that connects us with our Drupal system. Step 3: Connecting to Drupal For this step, we will first need to open up our empty main.as file so that we can add custom functionality to our Flash application. With this file open in our Flash IDE, our first task will be to connect with Drupal. Connecting to Drupal will require us to make a remote call to our Drupal installation, and then handle its response correctly. This will require the use of asynchronous programming techniques along with some standard remoting classes built into the ActionScript 3 library. I will spend some time here discussing the class used by ActionScript 3 to achieve remote communication. This class is called NetConnection. Using the NetConnection class The NetConnection class in ActionScript 3 is specifically used to achieve remote procedure calls within a Flash application. Luckily, this class is pretty straight forward and does not have a huge learning curve on understanding how to utilize it for communicating with Drupal. Using this class requires that we first create an instance of this class as an object, and then initialize that object with the proper settings for our communication. But let's tackle the creation first, which will look something like this in our main.as file: // Declare our Drupal connectionvar drupal:NetConnection = new NetConnection(); Now, you probably noticed that I decided to name my instance of this net connection drupal. The reason for this is to make it very clear that any place in our Flash application where we would like to interact with Drupal, we will do so by simply using our drupal NetConnection object. But before we use this connection, we must first specify what type of connection we will be using. In any NetConnection object, we can do this by providing a value for the variable objectEncoding . This variable lets the connection know how to structure the XML format when communicating back and forth between Flash and Drupal. Currently, there are only two types of encoding to choose from: AMF0 or AMF3. AMF0 is used for ActionScript versions less than 3, while AMF3 is used for ActionScript 3. ActionScript 1 and 2 are much less efficient than version 3, so it is highly recommended to use ActionScript 3 over 1 or 2. Since we are using ActionScript 3, we will need to use the AMF3 format, and we can provide this as follows: // Declare our Drupal connectionvar drupal:NetConnection = new NetConnection();drupal.objectEncoding = ObjectEncoding.AMF3; Now that we have an instance ready to go, our first task will be to connect to the Drupal gateway that we set up in the previous section. Connecting to a remote gateway Connecting to a remote gateway can be performed using the connect command on our drupal NetConnection object. But in order for us to connect, we must first determine the correct gateway URL to pass to this function. We can find this by going back to our Drupal installation and navigating to Administer | Services. In the Browse section, you will see a link to the servers available for remote procedure calls as shown in the following screenshot: For every listed server, we can click on each link to verify that the server is ready for communication. Let's do this by clicking on the link for AMFPHP, which should then bring up a page to let us know that our AMFPHP gateway is installed properly. We can also use this page to determine our AMFPHP gateway location, since it is the URL of this page. By observing the path of this page, we can add our AMFPHP server to our main.as file by combining the base URL of our site and then adding the AMFPHP services gateway to that base. // Declare our baseURL and gateway string.var baseURL:String = "http://localhost/drupal6";var gateway:String = baseURL + "/services/amfphp";// Declare our Drupal connectionvar drupal:NetConnection = new NetConnection();drupal.objectEncoding = ObjectEncoding.AMF3;// Connect to the Drupal gatewaydrupal.connect( gateway ); It is important to note that the connect routine is synchronous, which means that once this function is called, we can immediately start using that connection. However, any remote procedure call that we make afterwards, will be asynchronous, and will need to be handled as such. The function that can be used to make these remote procedure calls to Drupal is called call.
Read more
  • 0
  • 0
  • 2319
article-image-skinners-toolkit-plone-3-theming-part-2
Packt
20 Oct 2009
4 min read
Save for later

Skinner's Toolkit for Plone 3 Theming (Part 2)

Packt
20 Oct 2009
4 min read
(For more resources on Plone, see here.) Text editors The last key piece to successfully skinning a site is to choose a text editor or CSS editor that matches your needs and plays well with Plone. We are not talking about a word processor here, like Microsoft Word or Pages; rather, a text editor is a type of program used for editing plain text files. Text editors are often provided with operating systems or software development packages, and can be used to change configuration files and programming language source code. We'll look at a few of the more popular text editors that are appropriate for Plone development and theming. TextMate TextMate is a combination of text editor and programming tool that is exclusively for the Mac, and can be found at http://macromates.com. One of the key joys of working with TextMate is that it lets you open up an entire file structure at once to make navigation between related files easier. For Plone, this is essential. Your average file structure will look something like this: Rather than opening the entire buildouts folder, or even the plonetheme.copperriver folder, generally you only want to open the structure closest to the files you need in order to keep performance snappy—in this case, mybuildout[rockaway]/src/plonetheme.copperriver/plonetheme/copperriver/: As you can see, it opens the entire project in a clean interface with an easily navigable structure. Without this feature, skinning for Plone would be much more time-consuming. TextMate also offers numerous programmer-related tools: You can open two files at once (or more), and using the diff option you can compare the files easily Subversion (svn) support Ability to search and replace in a project Regular expression search and replace (grep) Auto-indent for common actions such as pasting text Auto-completion of brackets and other characters Clipboard history Foldable code blocks Support for more than 50 languages Numerous key combinations (for example, Apple + T opens a search window that makes it easy to locate a file) Themable syntax highlight colors Visual bookmarks to jump between places in a file Copy/paste of columns of text Bundles And much, much more The Bundle feature is one of the more interesting aspects of the tool. If you look at the HTML bundle, for example, it shows a list of common actions that you might wish to perform in a given document, and on the right, the code that spawns that action, and the hot-key that activates it. There's even a Zope/Plone TextMate support bundle found at http://plone.org/products/textmate-support that was developed by some of Plone's core developers. It enhances TextMate's already existing support for Python, XML, (X)HTML, CSS, and Restructured Text by adding features aimed specifically at the modern day Zope and Plone developer. For the geeks in the audience, the bundle's features include: Doctest support (restructured text with inline Python syntax and auto-indent of python code), pdb support (for debugging), ZCML support (no more looking up directives with our handy and exhaustive snippets), and a ZPT syntax that marries the best of both worlds (XML strictness with the goodness of TextMate's HTML support). This bundle plus TextMate's other capabilities make switching to developing for Plone on a Mac a good idea any day! As well as assigning a single key equivalent to a bundle item, it is possible to assign a tab trigger to the item. This is a sequence of text that you enter in the document and follow it by pressing the tab key. This will remove the sequence entered and then execute the bundle item. TextMate is full of hot-keys and features in general, yet it's surprisingly compact. Thankfully, the documentation is thorough. TextMate is a dream for themers and programmers alike. For those who are still new at CSS, another tool might be a good place to start, but for power users, TextMate is the primary tool of choice.
Read more
  • 0
  • 0
  • 3034

article-image-er-diagrams-domain-model-and-n-layer-architecture-aspnet-35-part2
Packt
20 Oct 2009
5 min read
Save for later

ER Diagrams, Domain Model, and N-Layer Architecture with ASP.NET 3.5 (part2)

Packt
20 Oct 2009
5 min read
1-tier 3-layer Architecture using a Domain Model Based on the class diagram in the first part, we will create a new simple 3-layered application using the entities defined in the above domain model. We will create a new ASP.NET Web Project in VS. This time, you should create two new folders inside your root web folder (using the Add New Folder option in VS): BL: This folder will contain all of the business logic domain classes DAL: This folder will contain the data access code files (for each entity) Layer 1: Data Access Layer (DAL) First, we will create a DAL class for each entity. We will name each DAL class using this naming pattern: EntityDAL. Let us see the CustomerDAL class: using DomainModel.BL;namespace DomainModel.DAL{ public class CustomerDAL { public static void AddCustomer(Customer cs) { using (SqlConnection con = new SqlConnection(SQLHelper.GetConnectionString())) { SqlParameter[] par = new SqlParameter[4]; par[0] = new SqlParameter("@customerID", cs.ID); par[0].Direction = ParameterDirection.Output; par[1] = new SqlParameter("@name", cs.Name); par[2] = new SqlParameter("@address", cs.Address); par[3] = new SqlParameter( "@phoneNo", cs.PhoneNumber); int rowNo = SQLHelper.ExecuteNonQuery( con, CommandType.StoredProcedure, "OMS_AddCustomer", par); cs.ID = Convert.ToInt32(par[0].Value); } } public static void DeleteCustomer(int customerID) { using (SqlConnection con = new SqlConnection(SQLHelper.GetConnectionString())) { SqlParameter[] par = new SqlParameter[1]; par[0] = new SqlParameter("@customerID", customerID); int rowNo = SQLHelper.ExecuteNonQuery( con, CommandType.StoredProcedure, "OMS_DeleteCustomer", par); } } public static void UpdateCustomer(Customer cs) { using (SqlConnection con = new SqlConnection(SQLHelper.GetConnectionString())) { SqlParameter[] par = new SqlParameter[4]; par[0] = new SqlParameter("@customerID", cs.ID); par[1] = new SqlParameter("@address", cs.Address); par[2] = new SqlParameter("@name", cs.Name); par[3] = new SqlParameter( "@phoneNo", cs.PhoneNumber); int rowNo = SQLHelper.ExecuteNonQuery( con, CommandType.StoredProcedure, "OMS_UpdateCustomer", par); } } public static void GetCustomer(Customer cs) { using (SqlConnection con = new SqlConnection(SQLHelper.GetConnectionString())) { SqlParameter[] par = new SqlParameter[1]; par[0] = new SqlParameter("@customerID", customerID); using (SqlDataReader dr = SQLHelper.ExecuteReader(con, CommandType.StoredProcedure, "OMS_GetCustomer", par)) { c = new Customer(); while (dr.Read()) { c.Name = SQLHelper.CheckStringNull(dr["Name"]); c.PhoneNumber = SQLHelper.CheckStringNull(dr["PhoneNo"]); c.Address = SQLHelper.CheckStringNull(dr["Address"]); c.ID = SQLHelper.CheckIntNull(dr["ID"]); } } } } public static List<Customer> GetAllCustomers() { List<Customer> cuList = new List<Customer>(); using (SqlConnection con = new SqlConnection(SQLHelper.GetConnectionString())) { using (SqlDataReader dr = SQLHelper.ExecuteReader(con,CommandType. StoredProcedure,"OMS_GetAllCustomer")) { while (dr.Read()) { Customer customer = new Customer(); customer.Name = SQLHelper.CheckStringNull(dr["Name"]); customer.PhoneNumber = SQLHelper.CheckStringNull(dr["PhoneNo"]); customer.Address = SQLHelper.CheckStringNull(dr["Address"]); customer.ID = SQLHelper.CheckIntNull(dr["ID"]); cuList.Add(customer); } } } return cuList; } }//end class} Here, we have used the SqlHelper class, which contains generic data access utility methods, so that we can avoid code repletion. Layer 2: Business Layer (BL) Next, we will create classes for each of the domain entities. We will put all of these classes under the new BL folder with this namespace: DomainModel.BL. Create a new C# class file named Customer.cs under the BL folder. Here is the first Customer class: using DomainModel.DAL;namespace DomainModel.BL{ public class Customer { private int _ID; private string _name; private string _address; private string _phoneNumber; private List<Customer> _customerCollection; public int ID { get { return _ID; } set { _ID = value; } } public string Name { get { return _name; } set { _name = value; } } public string Address { get { return _address; } set { _address = value; } } public string PhoneNumber { get { return _phoneNumber; } set { _phoneNumber = value; } } public List<Customer> CustomerCollection { get { return _customerCollection; } set { _customerCollection = value; } } public void Add() { CustomerDAL.AddCustomer(this); } public void Delete(int customerID) { CustomerDAL.DeleteCustomer(this.ID); } public void Update() { CustomerDAL.UpdateCustomer(this); } public void Load() { CustomerDAL.GetCustomer(this.ID); } public void GetAll() { this.CustomerCollection = CustomerDAL.GetAllCustomers(); } }//end class}//end namespace The CustomerDAL class is pretty simple: we are fetching the data from the database using data readers, and performing all data related operations using the Customer business object. This Customer class is defined in the Customer.cs class we created earlier. This BL class is calling DAL methods, so it needs a reference to the DAL namespace (using DomainModel.DAL). Similarly, the DAL class we created earlier used Customer business objects. That's why it also needed the BL namespace. We are using generics to create a collection of Customer objects. The BL communicates with DAL to get the data and perform updates. Now, we will see how the UI (which is under a different namespace) talks to BL without even knowing about DAL. Layer 3: The UI Layer Here is the code in the AllCustomers.aspx.cs page that shows a list of all of the customers from the DB (there is a data list on the web form, which will show a list of the customers): using DomainModel.BL;namespace DomainModel.UI { //page load private void FillAllCustomers() { Customer c = new Customer(); c.GetAll(); List<Customer> cuList = c.CustomerCollection; dtlstAllCustomer.DataSource = cuList; dtlstAllCustomer.DataBind(); } } So in the UI class, we neither have any data access code nor are we calling data access class methods from this layer (as was the case with the 1-tier 2-layer style we saw earlier in this article). We have a reference to the BL layer (using DomainModel.BL), and we are using the Customer business object to return a generic list of customer objects, which we are binding to the data list control (showing a list of all the customers). So the GUI layer does not know anything about the DAL layer, and is completely independent of it. The idea here is to understand how a 3-Layer architecture can provide more flexibility and loose-coupling to your project. In the next section, we will learn how we can use object data source controls to implement a 3-layer architecture without writing much code ourselves.
Read more
  • 0
  • 0
  • 2295
Modal Close icon
Modal Close icon