quinta-feira, dezembro 07, 2006

Migrating Struts Apps to Struts 2

Migrating Struts Apps to Struts 2

Posted by Ian Roughley on Sep 19, 2006 12:00 AM

Web Frameworks,

Most people are familiar with Struts, whether it is from direct experience or from reading articles or books. In this series of articles we will cover the features of Struts2 from a Struts perspective - by migrating a simple application.

Before we start the migration process, a little background to Struts2 is needed. The first part of this article will introduce Struts2, along with some of the core architectural differences that will help to conceptually put everything together. The second part will cover migrating the back-end - an in-depth look at the differences between actions; action related framework features; and action configuration. The final part of this article will address the user interface. We'll cover the architecture; talk about UI components, themes and tags; and put a new face on our application.

It is not my intent to cover every migration scenario available, but rather to introduce the concepts and new features available in Struts2 by starting from a common starting point. Armed with this knowledge, migrating an application of any size should be a piece of cake!

Introduction / History

The first version of Struts was released in June 2001. It was born out of the idea that JSPs and servlets could be used together to provide a clean separation between the view and the business or application logic of a web application. Before Struts, the most common options were to add business and application logic to the JSP, or to render the view from servlets using println() statements.

Since its release, Struts has become the de-facto standard for web application. With this popularity have come enhancements and changes - both to keep up with the ever-changing requirements for a web application framework, but also to match features with the ever-increasing number of competing frameworks available.

To that end, there have been several proposals for the next generation of Struts. The two alternatives that have become the most cohesive in the past year are Shale and Struts Ti. Shale is a component based framework, and just recently has become its own top-level Apache project, where Struts Ti continues the front controller or model-view-controller pattern that has made Struts so successful.

The WebWork project was started as a Struts revolution - as a fork of the Struts code to introduce new ideas, concepts and functionality that may not be compatible with the original Struts code - and it was first released in March 2002. WebWork is a mature framework, having undergone several minor and major releases.

In December 2005 it was announced that WebWork and the Struts Ti would join forces. Since that time, Struts Ti has become Struts Action Framework 2.0, and the successor to Struts.

Finally, it should be noted that neither the Struts nor WebWork projects are going away. While interest is high, and willing developers are available, both of these projects will continue - all the while having bugs fixed, and adding enhancements and new features.

A Request Walk-through

Before we start looking at the low level details of how to convert an application from Struts to Struts2, let's take a look at what the new architecture looks like by walking through the request processing.

As we walk through the request lifecycle you should notice one important fact - Struts2 is still a front controller framework. All of the concepts that you are familiar with will still apply.

This means:

  • Actions will still be invoked via URL's
  • Data is still sent to the server via the URL request parameters and form parameters
  • All those Servlet objects (request, response, session, etc.) are all still available to the Action

From a high-level overview, this is how the request is processed:

The processing of a request can be broken into these 6 steps:

  1. A request is made and processed by the framework - the framework matches the request to a configuration so that the interceptors, action class and results to use are known.
  2. The request passes through a series of interceptors - interceptors, and interceptor stacks, can be configured at a number of different levels for the request. They provide pre-processing for the request as well as cross-cutting application features. This is similar to the Struts RequestProcessor class which uses the Jakarta Commons Chain component.
  3. The Action is invoked - a new instance of the action class is created and the method that is providing the logic for this request is invoked. We will discuss this in more detail in the second part of this series; however, in Struts2 the configuration of the action can specify the method of the action class to be invoked for this request.
  4. The Result is invoked - the result class that matches the return from processing the actions' method is obtained, a new instance created and invoked. One possible outcome of the result being processed is rendering of a UI template (but not the only one) to produce HTML. If this is the case, then Struts2 tags in the template can reach back into the action to obtain values to be rendered.
  5. The request returns through the Interceptors - the request passes back through the interceptors in reverse order, allowing any clean-up or additional processing to be performed.
  6. The response is returned to the user - the last step is to return control back to the servlet engine. The most common outcome is that HTML is rendered to the user, but it may also be that specific HTTP headers are returned or a HTTP redirect is invoked.

As you may have noticed, there are some differences. The most obvious one is that Struts2 is a pull-MVC architecture. What does this mean? From a developers perspective it means that data that needs to be displayed to the user can be pulled from the Action. This differs from Struts, where data is expected to be present in beans in either the HTTP page, request or session scopes. There are other places that data can be pulled from, and we'll talk about those as the scenarios come up.

Configuring the framework

The first, and most important configuration, is the one that enables the web application framework within the servlet containers web.xml file.

The configuration that everyone should be familiar with for Struts is:





For Struts2 there are very few changes. The most significant is that the dispatcher has been changed from a servlet to a servlet filter. The configuration is just as easy as for a servlet, and shown here:




Similar to the servlet configuration, the filter configuration defines a name (for reference) and the class of the filter. A filter mapping links the name with the URI pattern that will invoke the filter. By default, the extension is ".action". This is defined in the default.properties file (within the Struts2 JAR file) as the "struts.action.extension" property.

SIDEBAR: The "default.properties" file is the place that many configuration options are defined. By including a file with the name "struts.properties" in the classpath of your web application, with different values for the properties, you can override the default configuration.

For Struts, the servlet configuration provides an init-param tag that defines the names of the files used to configure Struts. Struts2 does not have such a configuration parameter. Instead, the default configuration file for Struts2 has the name "struts.xml" and needs to be on the classpath of the web application.

SIDEBAR/TIP: Since there is a namespace separation between the Struts actions (with a ".do" extension) and the Struts2 actions (with a ".action") extension, there is no reason why they cannot co-exist within the same web application. This is a great way to start the migration process - add the necessary configuration, and start developing all new functionality in Struts2. As time and resources permit, the remaining actions can be converted. Or, the two frameworks can co-exist peacefully forever, since there is no reason that the existing action ever needs to be migrated. Another migration strategy is to update only the actions by changing the Struts2 extension to ".do". This allows the existing JSP's to remain the same and be re-used.

Deconstructing the Actions

In the request walk-through we spoke about some of the differences between Struts and Struts2 from a high level. Let's take it a step deeper now, and look at the differences between the structures of the actions in each framework.

Let's first review the general structure of the Struts action. The general form of the Struts action looks like this:

public class MyAction extends Action {
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
// do the work
return (mapping.findForward("success"));

When implementing a Struts action, you need to be aware of the following items:

  1. All actions have to extend the Action base class.
  2. All actions have to be thread-safe, as only a single action instance is created.
  3. Because the actions have to be thread-safe, all the objects that may be needed in the processing of the action are passed in the method signature.
  4. The name of the method that is invoked for the processing of the action is "execute" (there is a DispatchAction class available in Struts which can re-route the method to be executed to another method in the same action, however the initial entry point from the framework into the action is still the "execute" method).
  5. An ActionForward result is returned using a method from the ActionMapping class, most commonly via the "findForward" method call.

In contrast, the Struts2 action provides a much simpler implementation. Here's what it looks like:

public class MyAction {
public String execute() throws Exception {
// do the work
return "success";

The first thing you may have noticed is that the action doesn't extend any classes or interfaces. In fact, it goes further than this. By convention, the method invoked in the processing of an action is the "execute" method - but it doesn't have to be. Any method that follows the method signature public String methodName() can be invoked through configuration.

Next, the return object is a String. If you don't like the idea of string literals in your code, there is a helper interface Action available that provides the common results of "success", "none", "error", "input" and "login" as constants.

Finally, and perhaps the most revolutionary difference from the original Struts implementation, is that the method invoked in the processing of an action (the "execute" method) has no parameter. So how do you get access to the objects that you need to work with? The answer lies in the "inversion of control" or "dependency injection" pattern (for more information Martin Fowler has an informative article at http://www.martinfowler.com/articles/injection.html). The Spring Framework has popularized this pattern, however, the predecessor to Struts2 (WebWork) started using the pattern around the same time.

To understand the inversion of control better, let's look at an example where the processing of the action requires access to the current requests HttpServerRequest object.

The dependency injection mechanism used in this example is interface injection. As the name implies, with interface injection there is an interface that needs to be implemented. This interface contains setters, which in turn are used to provide data to the action. In our example we are using the ServletRequestAware interface, here it is:

public interface ServletRequestAware {
public void setServletRequest(HttpServletRequest request);

When we implement this interface, our simple action from above becomes a little more complex - but now we have a HttpServerRequest object to use.

public class MyAction implements ServletRequestAware {
private HttpServletRequest request;
public void setServletRequest(HttpServletRequest request) {
this.request = request;
public String execute() throws Exception {
// do the work using the request
return Action.SUCCESS;

At this point, some alarm bells are probably going off. There are now class level attributes in the action - which, although not thread-safe, is actually okay. In Struts2, an action instance is created for each request. It's not shared and it's discarded after the request has been completed.

There is one last step left, and that is to associate the ServletConfigInterceptor interceptor with this action. This interceptor provides the functionality to obtain the HttpServletRequest and inject it into actions that implement the ServletRequestAware interface. For the moment, don't worry about the details of the configuration - we'll go into much more detail in the next article. The important thing at the moment is to understand that the interceptor and the interface work hand-in-hand to provide the dependency injection to the action.

The benefit to this design is that the action is completely de-coupled from the framework. The action becomes a simple POJO that can also be used outside of the framework. And for those that encourage unit testing, testing a Struts2 action is going to be significantly easier than wrestling to get a Struts action into a StrutsTestCase or a MockStrutsTestCase unit test.

Conclusion / Wrap-Up

By now you should be familiar with the basics of Struts2 - the high level architecture and basic request workflow. You should be able to configure Struts2 in a servlet container, and know the differences between the action for Struts and Struts2.

In the next article we will introduce the example application that will be migrated, as well as building on the knowledge attained here to migrate the example applications' actions from Struts to Struts2. What we'll end up with is a working application using JSTL, JSP and Struts2. We'll also further investigate the differences between actions; configuration of actions and other framework elements; and talk more about the action related framework features.

About the author

Ian Roughley is a speaker, writer and independent consultant based out of Boston, MA. For over 10 years he has been providing architecture, development, process improvement and mentoring services to clients ranging in size from fortune 10 companies to start-ups. Focused on a pragmatic and results-based approach, he is a proponent for open source, as well as process and quality improvements through agile development techniques.

terça-feira, novembro 28, 2006


HTML Codes
Again, nothing to do with ASCII really, but has been requested by a number of you out there. To get special characters to show on an HTML web page, special codes can be used (ascii code or word) and are interpretted by the web browser.

quarta-feira, outubro 18, 2006

Windows Process Library

Windows Process Library

Go way to find what programs are doing in your task manager (windows taskmanager). it is a library with most common programs names, you just search by name and it shows what the program is!

terça-feira, agosto 01, 2006

Gmail: Help Center - How do I use Advanced Search?

How do I use Advanced Search?

Advanced search operators are query words or symbols that perform special actions in Gmail search. These operators allow you to find what you're looking for quickly and accurately. They can also be used to set up filters so you can organize your inbox automatically. Some of the most useful operators are listed below.

You can also use advanced search operators by clicking on Show search options beneath the Gmail search box.

Operator Definition Example(s)
from: Used to specify the sender Example - from:amy
Meaning - Messages from Amy
to: Used to specify a recipient Example - to:david
Meaning - All messages that were sent to David (by you or someone else)
subject: Search for words in the subject line Example - subject:dinner
Meaning - Messages that have the word "dinner" in the subject

Search for messages matching term A or term B*
*OR must be in all caps

Example - from:amy OR from:david
Meaning - Messages from Amy or from David
Used to exclude messages from your search Example - dinner -movie
Meaning - Messages that contain the word "dinner" but do not contain the word "movie"
label: Search for messages by label*
*There isn't a search operator for unlabeled messages
Example - from:amy label:friends
Meaning - Messages from Amy that have the label "friends"

Example - from:david label:my-family
Meaning - Messages from David that have the label "My Family"

Search for messages with an attachment Example - from:david has:attachment
Meaning - Messages from David that have an attachment
filename: Search for an attachment by name or type

Example - filename:physicshomework.txt
Meaning - Messages with an attachment named "physicshomework.txt"

Example - label:work filename:pdf
Meaning - Messages labeled "work" that also have a PDF file as an attachment

" "

Used to search for an exact phrase*
*Capitalization isn't taken into consideration

Example - "i'm feeling lucky"
Meaning - Messages containing the phrase "i'm feeling lucky" or "I'm feeling lucky"

Example - subject:"dinner and a movie"
Meaning - Messages containing the phrase "dinner and a movie" in the subject

( )
Used to group words
Used to specify terms that shouldn't be excluded

Example - from:amy(dinner OR movie)
Meaning - Messages from Amy that contain either the word "dinner" or the word "movie"

Example - subject:(dinner movie)
Meaning - Messages in which the subject contains both the word "dinner" and the word "movie"

in:anywhere Search for messages anywhere in your account*
*Messages in Spam and Trash are excluded from searches by default
Example - in:anywhere subject:movie
Meaning - Messages in All Mail, Spam, and Trash that contain the word "movie"
Search for messages in Inbox, Trash, or Spam Example - in:trash from:amy
Meaning - Messages from Amy that are in Trash
Search for messages that are starred, unread or read Example - is:read is:starred from:David
Meaning - Messages from David that have been read and are marked with a star
Used to specify recipients in the cc: or bcc: fields*
*Search on bcc: cannot retrieve messages on which you were blind carbon copied
Example - cc:david
Meaning - Messages that were cc-ed to David
Search for messages sent during a certain period of time*
*Dates must be in yyyy/mm/dd format.
Example - after:2004/04/16 before:2004/04/18
Meaning - Messages sent after April 16, 2004, but before April 18, 2004.*
*More precisely: Messages sent on April 17, 2004.

terça-feira, julho 25, 2006


tcpdump -i eth0 monitora todos os pacotes que passam pela interface eth0. Como se fosse um ps -ef para pacotes tcp e udp da rede

quinta-feira, junho 22, 2006

SAMBA 3.0 help

SAMBA 3 Helper

This web page is primarily for setting up Samba 3 on a BSD or Linux computer as a primary domain controller. If you simply want to share files and printers with windows machines on your network, using Samba 3, most of the things on this page will still be relevant to you. However, you will need to make changes to a few of the 'smb.conf' entries, such as security, local master, domain master, preferred master, domain logons, wins support, dns proxy, msdfs root, and host msdfs. These entries would typically be removed from smb.conf so that the default values will apply.

Setting up SAMBA 3 for a Domain Controller is a bit more difficult than setting up DHCP or DNS, or CUPS (for printing). But in order to get it 'up and running' as quickly as possible, you can follow the general instructions on this web page, which are intended as a quick 'how to' guide for Samba 3 as a Domain Controller. All of the necessary files for setting up a Samba-based domain controller for FreeBSD are included 'in line' and may be 'clipped out' and used as you see fit. For other operating systems, such as Linux, you may need to edit them slightly to get them to work. In particular, the shell scripts make use of the 'pw' application to add and modify users and groups, which is specific to FreeBSD.
Additional information can be found in the Samba documentation, which is installed in the local documentation tree on your computer, specifically the file 'samba/howto/FastStart.html' under the heading of 'Domain Controller'.

The following is a 'short list' of the things that need to be accomplished using the sample files, plus some additional information. The first step, of course, is to install the latest version of Samba 3 on your computer. Following that, you should do each of these steps in the order specified.

  1. modify and add the contents of the sample 'group' file to the /etc/group file on your system. You will need to check for 'overlap' to make sure that no duplicate groups (or duplicate group ID's) already exist in the file.
  2. Add the user 'administrator' using the appropriate utility (such as 'adduser'), and using the 'samba' group as the primary group. Then, add it to the wheel group.
  3. Copy the 'smb-' scripts into the /usr/local/sbin/ directory, and mark them 'executable'. This can be done using 'chmod 555' on each of them.
  4. Copy the 'samba_dns_update' script to /usr/local/sbin/, and mark it 'executable'.
  5. modify 'smb.conf', specifically those entries that contain the following:
    1. the IP address ''
    2. The domain name 'WORKGROUP.local'
    3. The machine name 'FreeBSDServer'
    Then, copy the 'smb.conf' file into the appropriate location. On FreeBSD, this would be /usr/local/etc/smb.conf .
  6. Create a directory /usr/local/lib/samba/profiles/, make it world-writable
  7. Create a directory /usr/local/lib/samba/drivers/, make it world-readable
  8. Create a directory /usr/local/lib/samba/netlogon/, make it world-writable
  9. Start Samba (or re-start the system). Once Samba is up and running, perform the following:
    1. Run the script 'mapgroup.sh'.
    2. smbpasswd -a root (and enter root password)
    3. smbpasswd -a administrator (and enter administrator password)
  10. If necessary, perform the following manually
    1. add a machine to the domain by first creating a user 'machinename$' (where 'machinename' is the NETBIOS name of the machine) as a member of the group 'machines'. The 'smb-add-machine' script should perform this action.
    2. use smbpasswd -m machinename$ to make it 'official'.

NOTE: The paths '/usr/local/lib/samba', '/usr/local/sbin', and '/usr/local/etc' are all implementation-dependent. You can use 'whereis' and other utilities to determine where the files and applications reside.

At this point, so long as DHCP, DNS, and CUPS are correctly configured, your Samba installation should allow your UNIX or Linux server to operate as a Primary Domain Controller (PDC) and DHCP server for your network.

The Files

The contents of the various files are shown here. You can 'clip' the text out of the html text and paste it into the appropriately named file, modifying the text as needed for your operating system, machine name, domain name, and network settings.


#======================= Global Settings =====================================
# modify these for your domain name
workgroup = WORKGROUP.local
realm = WORKGROUP.local
# modify these for your server name
netbios name = FreeBSDServer
server string = FreeBSDServer Domain Controller for WORKGROUP.local

# modify these next entries for your IP address and netmask. The settings
# below reflects 192.168.1/24 and 127/8, with IP addres and
hosts allow = 192.168.1. 127.
socket address =

# setting up as a domain controller. 'man smb.conf' for explanation
security = user
local master = yes
domain master = yes
preferred master = yes
domain logons = yes
wins support = yes
dns proxy = yes
os level = 33
msdfs root = yes
host msdfs = yes
obey pam restrictions = yes
time server = yes
# force LM announcements every 2 minutes
lm announce = yes
lm interval = 120

# global file masks
directory mask = 0777
force directory mode = 0555
create mask = 0666
force create mode = 0444

# name resolution
name resolve order = wins bcast

# printers - configured to use CUPS and automatically load them

load printers = yes
printcap name = cups
printing = cups

# Backend to store user information in. New installations should
# use either tdbsam or ldapsam. smbpasswd is available for backwards
# compatibility. tdbsam requires no further configuration.
# if you want to have a backup domain controller, or participate
# as part of a larger domain, you will need to use 'ldapsam' and
# do some additional configuration.
; passdb backend = ldapsam
passdb backend = tdbsam

# Uncomment this if you want a guest account, you must add this to /etc/passwd
# otherwise the user "nobody" is used
; guest account = pcguest

# Using the following line enables you to customise your configuration
# on a per machine basis. The %m gets replaced with the netbios name
# of the machine that is connecting.
# Note: Consider carefully the location in the configuration file of
# this line. The included file is read at that point.
; include = /usr/local/etc/smb.conf.%m

# scripts invoked by Samba

# These scripts are used on a domain controller or stand-alone
# machine to add or delete corresponding unix accounts;
# NOTE: the original entries are commented out. They may be valid on
# some operating systems. The ones not commented out invoke the
# script files that are copied to '/usr/local/sbin'. You should
# update this section based upon the requirements of your OS.
; add user script = /usr/sbin/useradd %u
; add group script = /usr/sbin/groupadd %g
; add machine script = /usr/sbin/adduser -n -g machines -c Machine -d /dev/null -s /bin/false %u
; delete user script = /usr/sbin/userdel %u
; delete user from group script = /usr/sbin/deluser %u %g
; delete group script = /usr/sbin/groupdel %g
add user script = /usr/local/sbin/smb-add-user %u
add group script = /usr/local/sbin/smb-add-group %g
add machine script = /usr/local/sbin/smb-add-machine %u
add user to group script = /usr/local/sbin/smb-add-user-group %u %g
delete user script = /usr/local/sbin/smb-rm-user %u
delete user from group script = /usr/local/sbin/smb-rm-user-group %u %g
delete group script = /usr/local/sbin/smb-rm-group %g

# 'wins hook' script - call to 'nsupdate' to update DNS automatically
wins hook = /usr/local/sbin/samba_dns_update

# log files

# this tells Samba to use a separate log file for each machine
# that connects
log file = /var/log/samba/log.%m

# Put a capping on the size of the log files (in Kb).
max log size = 50

# login scripts

# if you enable domain logons then you may want a per-machine or
# per user logon script
# run a specific logon batch file per workstation (machine)
; logon script = %m.bat
# run a specific logon batch file per username
; logon script = %U.bat

# user profiles (default is sufficient, see 'profiles' share)

# Where to store roving profiles (only for Win95 and WinNT)
# %L substitutes for this servers netbios name, %U is username
# You must uncomment the [Profiles] share below
logon path = \\%L\Profiles\%U

# socket options

# Most people will find that this option gives better performance.
# See the chapter 'Samba performance issues' in the Samba HOWTO Collection
# and the manual pages for details.
# You may want to add the following on a Linux system:
socket options = TCP_NODELAY

#============================ Share Definitions ==============================

# netlogon directory, necessary for Domain Logons
comment = Network Logon Service
path = /usr/local/lib/samba/netlogon
guest ok = yes
writable = no
share modes = no

# 'Roving Profile' share (in lieu of the user's home directory)
path = /usr/local/lib/samba/profiles
browseable = no
guest ok = yes
writable = yes

# 'printers' share (no need to individually declare them if the printers
# are being automatically loaded and CUPS is properly configured)
comment = All Printers
path = /var/spool/samba
browseable = no
# Set public = yes to allow user 'guest account' to print
guest ok = yes
writable = no
printable = yes
printer admin = @wheel

# path to printer drivers (see CUPS documentation)
comment = Printer Drivers
path = /usr/local/lib/samba/drivers
browseable = yes
guest ok = yes
writable = no
printable = no


You will need to add the following text to the end of the '/etc/group' file. Make sure that there are no overlaps with names or ID's for any existing groups. You can edit the group ID's as needed.
(You should also change 'WORKGROUP' to the name of your domain, or else remove it if you do not want a group that represents the domain)

# these group entries need to be added to the '/etc/group' file
# samba requires a 'machines' group equal to 100
# locally defined groups. the first is the domain group 'WORKGROUP'
# you should change this depending upon the domain
# group added for 'dhcpd'
# group added for 'samba' (default for all new Samba users)
# additional 'operator' groups for Samba - print, account, backup


The following script will associate the various 'Samba' groups (compatible with Windows) with UNIX groups defind in the '/etc/group' file. Some of the examples were left 'as-is' and commented out, using examples obtained from the Samba documentation. Additional information as comments has been placed at the end of the script in order to document the correct 'RID' values, should you need to re-create the groups yourself.
(You should make sure that each of the groups referenced in the script actually exist, and add them to the '/etc/group' file if they do not).

#### Keep this as a shell script for future re-use

# assign well known groups for the domain
# net groupmap add ntgroup="Domain Admins" unixgroup=wheel type=d rid=512
# net groupmap add ntgroup="Domain Users" unixgroup=samba type=d rid=513
# net groupmap add ntgroup="Domain Guests" unixgroup=nobody type=d rid=514

net groupmap modify ntgroup="Domain Admins" unixgroup=wheel
net groupmap modify ntgroup="Domain Users" unixgroup=samba
net groupmap modify ntgroup="Domain Guests" unixgroup=nobody

# now, do the local groups. Change 'WORKGROUP' to the group that is
# associated with the domain name.
net groupmap modify ntgroup="Administrators" unixgroup=wheel
net groupmap modify ntgroup="Users" unixgroup=samba
net groupmap modify ntgroup="Guests" unixgroup=guest
net groupmap modify ntgroup="Power Users" unixgroup=WORKGROUP
net groupmap modify ntgroup="Account Operators" unixgroup=account
net groupmap modify ntgroup="System Operators" unixgroup=operator
net groupmap modify ntgroup="Print Operators" unixgroup=print
net groupmap modify ntgroup="Backup Operators" unixgroup=backup
net groupmap modify ntgroup="Replicators" unixgroup=staff

# list of domain groups and RID's
# Domain Admins 200H
# Domain Users 201H
# Domain Guests 202H

# list of local groups
# Administrators 26
# Users 27
# Guests 28
# Power Users 29
# Account Operators 30
# System Operators 31
# Print Operators 32
# Backup Operators 33
# Replicators 34


This script is called by Samba to automatically update DNS. You should modify it as necessary for your system, and change the 'WORKGROUP.local' and IP address information accordingly.

# Example script for "wins hook". This attempts to update the DNS with
# new A records for the NETBIOS name that Samba passes us. We do this
# the simple way, by deleting all DNS records for the name and then
# readding all the expected 'A' records.
# Written by Stephen Rothwell

# Configurable things
# The domain in which to create names
# N.B. include the trailing dot
# It is a good idea to use a subdomain of your primary domain to ensure
# that rogue machines can't take over (or delete) important names on
# your network.

# The DNS TTL to give the records (in seconds)
# NETBIOS name types that we want to create DNS records for:
# 20 is server
# 00 is workstation
# 03 is user
USEFUL_TYPES="20 00 03"
# The name of a cache file to use to avoid continual updates
# of the same name and IP addresses. If you comment this out
# then the cache is not kept at all.

if [ $# -lt 4 ]; then
echo "Usage: $0 op name type ttl [ip_addr ...]" 1>&2
echo " op is one of add, refresh, delete" 1>&2
echo " name is the NETBIOS name" 1>&2
echo " type is the NETBIOS name type" 1>&2
echo " ttl is the NETBIOS time to live" 1>&2
echo " ip_addr's are the remaining IP addresses for this name" 1>&2
exit 1

NSUPDATE=`which nsupdate`
[ -x "$NSUPDATE" ] || NSUPDATE=/usr/bin/nsupdate
[ -x "$NSUPDATE" ] || NSUPDATE=/sbin/nsupdate
[ -x "$NSUPDATE" ] || NSUPDATE=/usr/sbin/nsupdate
[ -x "$NSUPDATE" ] || {
echo "Cannot find nsupdate." 1>&2
exit 1

shift 4

for i in $USEFUL_TYPES
[ "$TYPE" = "$i" ] && do_update=1
[ $do_update = 1 ] || exit 0

if [ -n "$CACHE_FILE" ]; then
if [ -r "$CACHE_FILE" ]; then
fgrep -q -x -i "$NAME $IP_ADDRS" "$CACHE_FILE" &&
exit 0
grep -v -i "^$NAME " "$CACHE_FILE" >"$CACHE_FILE".$$
echo "$NAME $IP_ADDRS" >>"$CACHE_FILE".$$
mv "$CACHE_FILE" "$CACHE_FILE".old 2>/dev/null

echo update delete $NAME.$DOMAIN
for i in $IP_ADDRS
echo update add $NAME.$DOMAIN $TTL A $i
} 2>/dev/null | $NSUPDATE >/dev/null 2>&1 &

exit 0


Script called by Samba to add a group. Modify this for your system, as needed.

# called by samba to add a group

echo `date` "/bin/sh" $- $0 "$@" >>/var/log/smb.user.group.log

x=`pw groupnext`
if $( test ! -n "$x" )
echo "unable to get next group ID";
if $( test -n "$1" )
pw groupadd -n $1 -g $x ;


Script called by Samba to add a machine, by adding a user to the 'machines' group. Modify this for your system, as needed. If this script does not function correctly, you will not be able to join a domain without manually adding the machine as a user, both to the UNIX password database and the Samba password database.

# called by samba to add a machine as a special user

echo `date` "/bin/sh" $- $0 "$@" >>/var/log/smb.user.group.log

x=`pw usernext`
if $( test ! -n "$x" )
echo "unable to get next user ID";
if $( test -n "$1" )
pw useradd -q -n $1 -u $x -d /dev/null -s /sbin/nologin -g machines ;


Script called by Samba to add a user. Modify this for your system, as needed.

# called by samba to add a user

echo `date` "/bin/sh" $- $0 "$@" >>/var/log/smb.user.group.log

x=`pw usernext`
if $( test ! -n "$x" )
echo "unable to get next user ID";
if $( test -n "$1" )
pw useradd -q -n $1 -u $x -d /dev/null -s /sbin/nologin -g samba ;


Script called by Samba to add a user to a group. Modify this for your system, as needed.

#!/bin/sh -f
# the '-f' parameter prevents file name expansion

echo `date` "/bin/sh" $- $0 "$@" >>/var/log/smb.user.group.log

if ( test -n "$1" )
if ( test -z "$2" )
echo "missing group name";
x=`pw groupshow -n $2 | sed s/:/,/g ` ;

for i in $x ; do
if ( test $y -gt 3 )
if ( test "$u" = "$i" )
exit 1;
y=$(expr $y + 1)

unset IFS

pw groupmod -n $g -m $u ;



Script called by Samba to remove a group. Modify this for your system, as needed.

# called by samba to delete a user

echo `date` "/bin/sh" $- $0 "$@" >>/var/log/smb.user.group.log

if $( test -n "$1" )
pw groupdel -n $1;


Script called by Samba to remove a user. Modify this for your system, as needed.

# called by samba to delete a user

echo `date` "/bin/sh" $- $0 "$@" >>/var/log/smb.user.group.log

if $( test -n "$1" )
pw userdel -n $1;


Script called by Samba to remove a user from a group. Modify this for your system, as needed.
(I am rather proud of this script, actually, being one of the more creative things I've done recently)

#!/bin/sh -f
# the '-f' parameter prevents file name expansion

echo `date` "/bin/sh" $- $0 "$@" >>/var/log/smb.user.group.log

if ( test -n "$1" )
if ( test -z "$2" )
echo "missing group name";
x=`pw groupshow -n $2 | sed s/:/,/g ` ;

for i in $x ; do
if ( test $y -gt 3 )
if ( test "$u" = "$i" )
c="pw groupmod -n $g -M";
elif ( test -z "$m")
y=$(expr $y + 1)

unset IFS
if ( test -n "$c" )
eval $c $m ;

Additional Configuration

Of course, you will need to add shares to your 'smb.conf' file, but this should be relatively straightforward. For more information you can use 'man smb.conf' or look at the sample 'smb.conf' file that was installed when you installed Samba. The shares that were put into the 'smb.conf' sample, above, are the minimum required to get the system running properly. Still, they can serve as examples for setting up your own shares. A few were commented out that demonstrate typical read/write shares. If you want to set up access lists, make the shares unlistable or read-only, you should check the documentation on Samba and smb.conf for information on how to do that. The point of the files here is to "get you started" and not be a general guide for administering your system.

Backing Up your Configuration

It is VERY VERY IMPORTANT that you back up your system configuration as often as you can. Samba, like any software, is not perfect, and files can occasionally become corrupted for a number of reasons, including power outages. Because this is a domain controller, you should back your initial configuration at the very least, and each time you add a workstation or a user to the system. This way, if the database becomes corrupt or loses data, you can restore everything without having to 'rejoin the domain' on every workstation. The configuration nightmare of THAT scenario is not something I'd wish upon anyone. And this goes double if you are using the 'TDB' system rather than LDAP (or if you are using LDAP without a backup domain controller to restore from).

If you are using the TDB method (the default) to store the configuration data, you should make sure you shut down 'smbd' and 'nmbd' before you back up the data. To do this, you can use the following commands:
smbcontrol nmbd shutdown
smbcontrol smbd shutdown
This will shut down all running instances of nmbd and smbd. Next, you need to know where all of the files are stored. If you enter 'man tdbbackup' you will get a hint of where they MIGHT be, but this is sometimes less than helpful. However, on a FreeBSD system, the files you are interested in are located in the following directories:
Again, on your system it may differ slightly (see 'man tdbbackup'). Once you have located the files, backing them up is as changing to the appropriate directory, and entering the following command:
tdbbackup *.tdb
This will generate a group of files with '.bak' extensions that are backups of the TDB files in the directory. Using the same application you can also verify AND automatically restore any backed up tdb files.

Since the password information is stored in the 'private' directory ('/usr/local/private' on a FreeBSD system), it is extremely important that you back THIS up. Not making a backup of the password information for a domain controller might mean a weekend or all-night stay at 'the office' re-configuring everybody's workstation for the 'new' domain because when you re-initialize a domain controller, all of the security ID's change, and windows machines will recognize that as a DIFFERENT domain, and all of the user settings for the OLD logon will be lost, and though you can recover them with a little creativity, it's not the easiest process in the world, and requires knowledge of the registry, re-assignment of security settings. and some creativity in 'hacking' certain registry entries. But someday I might write an application to do just this. It IS something that can be rather painful to deal with if your domain controller ever goes down, and you have to create a new one. And I've seen this happen before.
NOTE: The procedure to recover user settings after a domain crash on a Windows 2000 or XP workstation can be found HERE.

Additional SAMBA-related Links

www.Samba.org Official Samba web site, with the latest code, patches, and announcements
9-user Server Example Article from 'www.informit.com', regarding an example 9 user network configuration using Samba 3. It details the necessary configuration file entries for 'smb.conf' and for CUPS to meet the requirements of the example network.

©2005 by Stewart~Frazier Tools, Inc. - all rights reserved
Last Update: 6/28/2005
Back to 'Windows to Unix' page
Back to S.F.T. Inc. main page

quarta-feira, maio 10, 2006

Projeto Nheengatu PDF

Projeto Nheengatu: O objetivo principal do Projeto Nheengatu é utilizar ao máximo o HTML, a linguagem de marcação, acredito eu, mais utilizada do mundo. Baseada no DTD SGML, o HTML está na marcação de procedimentos em documentos de hipertexto espalhados por toda a Internet. O HTML é uma linguagem comum, como o Nheengatu. O Projeto Nheengatu é uma biblioteca simples de classes Java baseada no iText ( http://www.lowagie.com/iText ) utilizada para a abstração de um conjunto de tags e textos HTML provendo sua exibição em um arquivo PDF. É isso aí, o HTML além do browser! Imagine uma tabela do HTML utilizada na camada de apresentação de uma aplicação J2EE para exibir um conjunto de registros devidamente marcados. Ao se clicar no link 'Imprimir' um Servlet será invocado e retornará para o cliente um documento PDF, onde a marcação do HTML foi reutilizada. Para incluir este recurso na minha aplicação, bastou inserir dois comentários no início e no fim do código HTML a ser exibido no documento PDF

quarta-feira, abril 19, 2006

Compiere ERP sites no Brasil

O Compiere é um programa de gestão livre que já existe no mercado desde 2000. Mesmo sendo gratuito, em sua forma original, ele necessita do banco de dados Oracle para poder funcionar. Esse tem um custo muito alto e assim acaba impossibilitando o uso do Compiere por empresas sem grandes possibilidades de investimentos na área de tecnologia de informação.

Compiere Brasil - Compiere com Postgresql

CompierBR Consultoria que implanta o ERP - Compiere com Postgresql


terça-feira, abril 18, 2006

Windows 98 SE OEM Boot Disk

Superdownloads :: Manutenção e Reparo de Sistema :: Windows 98 SE OEM Boot Disk
Como gerar boot disks
Geração do disco de boot do Windows 98 Second Edition, com suporte universal aos drivers de CD-ROM.

Requerimentos e notas:
Requer disquete formatado.

Roda em Windows 95, 98, NT, 2000, ME, XP

Boot Disks IDE CDrom Drivers Included

DOS 5.0 | Mirror1 | 2
DOS 6.0 | Mirror1 | 2
DOS 6.21 | Mirror1 | 2
DOS 6.22 | Mirror1 | 2
DOS 6.22 5 1/4 1.2 meg disk | Mirror
Windows 95 Original | Mirror1 | 2
Windows 95 Version B | Mirror1 | 2
Windows 98 OEM | Mirror1 | 2
Windows 98 Custom, No Ramdrive | Mirror1 | 2 | 3
Windows 98 SE OEM | Mirror1 | 2 | 3
Windows 98 SE Custom, No Ramdrive | Mirror1 | 2 | 3
Windows Me OEM | Mirror1 | 2 | 3
Windows Me Custom, No Ramdrive | Mirror1 | 2 | 3

NTFS Bootdisks And Bootable CDs

Windows 2000 And NT Setup Disk Sets

W2K Pro:
Disk1 | Mirror
Disk2 | Mirror
Disk3 | Mirror
Disk4 | Mirror
makeboot.exe | Mirror
makebt32.exe | Mirror

W2K: Server | Mirror
W2K: Advanced Server | Mirror

NT4: Workstation | Mirror
NT4: Server | Mirror
NT 3.51: Micron

Windows XP 6 Disk Setup Set

XP Home/Pro Original/SP1/SP2

XP Quick Boot Diskette xpquick.zip | xpquick.exe | Read.1st

NTFS Bootdisks And Bootable CDs

Non-Windows Based Image Files W/ImageApp

DOS 6.22 | Win98 | Win98SE | WinMe
Special Disk For Bios Flashing

I'm glad that you have chosen my site to help you get your PC working again. It would be really nice to show your appreciation for my efforts by donating a mere $3 to help me continue to maintain this website.

If you have a credit card or PayPal account you may donate $3 to Bootdisk.Com by clicking on this link. To choose your own level of support click here. Thank you.

Or, while formatting you could always pop a few dollars in an envelope to Ed Jablonowski, 56 Kossman St., East Brunswick, NJ 08816 USA. Thanks again for visiting and good luck getting your PC back up. Ed.

Updated fdisk for Windows 98 bootdisks and/or systems for hard drives over 64 Gig | Mirror1 | 2 | Readme

1. Most of the files above are disk images. Download the file to your C: drive, put a fresh disk in your A: drive, then click on the file to create the bootdisk.

2. If the Primary link is down, use a [Mirror] site to download the file.

3. The W2K Pro disks are zipped images from the MS CD. Best bet is to download them, upzip them to a new folder where you also put makeboot.exe and makebt32.exe into and then run one of the makeboot utils depending on if you're in dos or windows to create the diskset. Or, one can use Winimage to just create a single bootdisk.

4. The Win9X OEM disks are Images of the Microsoft bootdisks that came with your OS. They put the utilities you need in a ramdrive, or virtual disk which is usually the next drive letter up from your hard drive partitions. Use my Custom disks for a faster, easier to use utility.

Extra special thanks to Frashii, Matt H., and 1gighost.com

Also thanks to:

Bootdisks - PC Support - Essential Utilities Bootdisk.Com

segunda-feira, abril 03, 2006

Validação de formulários HTML com JavaScript

Validação de formulários HTML com JavaScript
Márcio d'Ávila, 21 de outubro de 2003. Revisão 4, 24 de maio de 2005.
Categoria: Internet: Cliente: JavaScript

O uso de expressões regulares em JavaScript pode tornar bem compacta, flexível e poderosa a validação cliente (no navegador web) de campos de formulário, algo muito recomendado como pré-verificação do conteúdo de um formulário antes de submetê-lo ao servidor. O recurso de expressão regular surgiu no JavaScript 1.2, implementado desde a versão 4 de ambos os principais navegadores: Internet Explorer e Netscape Navigator (atual Mozilla).

Para cada tipo de conteúdo ? numérico, data, endereço eletrônico etc. ? podemos montar uma expressão regular apropriada para sua validação, de acordo com o formato e características desejadas. A validação do conteúdo de um campo através de uma expressão regular para o seu respectivo tipo consiste simplesmente em aplicar o padrão da expressão regular e testá-lo no texto desejado, com o método test( ).

Começamos com uma validação bem trivial: a validação de entrada de um número inteiro não-negativo sem sinal, ou seja, apenas dígitos.

Use o formulário de exemplo ao lado para validar um número apenas com dígitos (inteiro não-negativo sem sinal).

Em JavaScript, uma expressão regular é delimitada por uma barra / inicial e outra final. Cada expressão de validação sempre começa com ^ (início de linha) e termina com $ (fim de linha), para garantir que abrange o conteúdo inteiro do texto (parâmetro) a ser validado.

Existe uma seqüência de expressão regular que significa um dígito (0 a 9): \d. Adicionando um + após essa seqüência, significa "uma ou mais ocorrências da seqüência precedente". Isto é, um ou mais dígitos. Note que isso implica o preenchimento obrigatório; é melhor que o caso do campo não preenchido (vazio) seja tratado à parte. Assim, temos a expressão regular completa para validar um número apenas composto por dígitos:

reDigits = /^\d+$/;

Apresentamos agora um exemplo mais complexo de uso de expressão regular para a validação de números reais em ponto flutuante (decimal). As expressões definidas permitem, como opcionais: sinal, separadores de milhar e casas decimais. Não é tratada neste exemplo a notação científica (com expoente).

Use o formulário de exemplo ao lado para validar um número real decimal. Escolha pela caixa de seleção o idioma usado na expressão regular de validação, que define os carateres usados como separador de milhar e casas decimais.

As expressões regulares utilizadas nesta validação estão apresentadas no quadro a seguir.

reDecimalPt = /^[+-]?((\d+|\d{1,3}(\.\d{3})+)(\,\d*)?|\,\d+)$/;
reDecimalEn = /^[+-]?((\d+|\d{1,3}(\,\d{3})+)(\.\d*)?|\.\d+)$/;

Agora, vamos entender esse emaranhado de símbolos. Apresentarei a explicação para a expressão regular em Português. A lógica é idêntica para Inglês, trocando apenas os separadores de milhar e decimal (vírgula e ponto).

* [+-]? indica um caractere opcional (?), de sinal positivo ou negativo ([+-]).
* A seguir, o número efetivo está agrupado em duas formas de apresentação possíveis: com uma parte inteira, ou apenas com a parte decimal; a sintaxe (forma1|forma2) representa a condição "ou" entre as duas formas.
* Entender a 2ª forma, apenas com a parte decimal, é mais simples: \,\d+ significa um número iniciado por vírugula (\,) seguido de um ou mais (+) dígitos numéricos (\d). Isso significa que o número ,123 é aceito como válido, ficando o zero da parte inteira subentendido (0,123). Se esta forma não for desejada, basta retirar esta condição e deixar apenas a 1ª forma, que obriga uma parte inteira.
* Na primeira forma, a parte decimal ao final é opcional. Portanto, ela é exatamente a 2ª forma, mas delimitada pelo operador ? que denota opcionalidade: (\,\d*)?.
* Para a parte inteira, existe mais uma condição "ou", permitindo duas apresentações possíveis: com ou sem separador de milhar. Se a parte inteira não usar separador de milhar, deve consistir apenas de um ou mais dígitos: \d+.
* Se houver separador de milhar (isto é, um ponto a cada grupo de 3 dígitos), a parte inteira deve iniciar por um a 3 dígitos ? \d{1,3} ? seguindo-se um ou mais (+) grupos de um ponto e 3 dígitos: (\.\d{3})+.

Note que a expressão foi montada de forma a não aceitar espaços antes ou depois do texto, nem entre o sinal e o número. Obviamente, isso e tudo o mais pode ser adaptado de acordo com a necessidade.

Finalizamos mostrando um caso específico bem comum da validação de números decimais: valores financeiros.
Valor (financeiro):

Use o formulário de exemplo ao lado para validar um valor financeiro.

O valor financeiro é uma simplificação do número decimal visto anteriormente, não permitindo sinal e exigindo sempre 2 casas decimais e separador de milhar obrigatório. Separadores de decimal e milhar estão no formato em português: vírgula e ponto, respectivamente. A expressão regular usada é a seguinte:

reMoeda = /^\d{1,3}(\.\d{3})*\,\d{2}$/;


Use o formulário de exemplo ao lado para validar uma data. Escolha pela caixa de seleção a complexidade da expressão regular usada na validação.

As expressões regulares utilizadas nesta validação estão apresentadas no quadro a seguir. As expressões 4 e 5 estão exibidas em mais de uma linha apenas para melhor legibilidade, mas devem ser consideradas como em uma única linha cada.

reDate1 = /^\d{1,2}\/\d{1,2}\/\d{1,4}$/;
reDate2 = /^[0-3]?\d\/[01]?\d\/(\d{2}|\d{4})$/;
reDate3 = /^(0?[1-9]|[12]\d|3[01])\/(0?[1-9]|1[0-2])\/(19|20)?\d{2}$/;
reDate4 = /^((0?[1-9]|[12]\d)\/(0?[1-9]|1[0-2])|30\/(0?[13-9]|1[0-2])
reDate5 = /^((0[1-9]|[12]\d)\/(0[1-9]|1[0-2])|30\/(0[13-9]|1[0-2])

Estas expressões regulares vão do mais simples ao mais completo, da seguinte forma:

1. Simples ? valida apenas o uso de dígitos, nas posições e quantidade certas: 1 a 2 dígitos para dia e para mês, 1 a 4 dígitos para ano.
2. Média ? testa os dígitos possíveis em cada posição: o primeiro dígito do dia, se houver, deve ser de 0 a 3 ([0-3]?\d); o primeiro dígito do mês, se houver, deve ser 0 ou 1 ([01]?\d); passamos a aceitar apenas 2 ou 4 dígitos para o ano.
3. Avançada ? garante as faixas de valores corretas para dias 1 a 31 ((0?[1-9]|[12]\d|3[01])) e meses 1 a 12 ((0?[1-9]|1[0-2])). E aqui optamos por forçar os 2 primeiros dígitos do ano (correspondentes ao século), quando fornecidos, a serem 19 ou 20 ((19|20)?\d{2}).
4. Completa ? valida os dias permitidos de acordo com o mês. Para este último, foram criados três grupos alternativos de pares dia/mês:
* Os dias 1 a 29 ((0?[1-9]|[12]\d)) são aceitos em todos os meses (1 a 12): (0?[1-9]|1[0-2])
* Dia 30 é válido em todos os meses, exceto fevereiro (02): (0?[13-9]|1[0-2])
* Dia 31 é permitido em janeiro (01), março (03), maio (05), julho (07), agosto (08), outubro (10) e dezembro (12): (0?[13578]|1[02]).
5. Tradicional ? data no formato DD/MM/AAAA, basicamente é a data Completa, porém sem a opcionalidade do zero à esquerda no dia ou mês menor que 10 e sem a opcionalidade e verificação de século no ano, aceitando qualquer seqüência de 4 dígitos (\d{4}) como ano.

A única coisa que a expressão mais completa (e complexa) não é capaz de testar é a validade do dia 29/fev apenas para anos bissextos.

A obrigatoriedade ou não de dois dígitos no dia e no mês é facilmente controlada com a ausência ou não do operador de opcionalidade ? após o primeiro dígito. As expressões apresentadas também ofereceram diversas possibilidades para a validação dos dígitos do ano.

Use o formulário de exemplo ao lado para validar um horário ou tempo. Escolha pela caixa de seleção a complexidade da expressão regular usada na validação.

As expressões regulares utilizadas nesta validação estão apresentadas no quadro a seguir. As possibilidades de variação para horário (hora/minutos/etc. de um dia) ou tempo (período de tempo decorrido, independente de dia) são ilimitadas. Exemplificamos aqui alguns casos típicos, que podem ser combinados e alterados conforme a necessidade.

reTime1 = /^\d{2}:\d{2}$/;
reTime2 = /^([0-1]\d|2[0-3]):[0-5]\d$/;
reTime3 = /^(0[1-9]|1[0-2]):[0-5]\d$/;
reTime4 = /^\d+:[0-5]\d:[0-5]\d$/;
reTime5 = /^\d+:[0-5]\d:[0-5]\.\d{3}\d$/;

1. Horário HH:MM simples ? aceita dois pares de dois dígitos separados por dois-pontos (:); pode ser usado para hora:minutos ou ainda para minutos:segundos, porém não valida as faixas de valor válidos para os dígitos, aceitando assim qualquer valor entre 00 e 99.
2. Horário HH:MM 24h ? aceita horas na faixa 00-23 e minutos 00-59, separados por dois-pontos.
3. Horário HH:MM 12h ? aceita horas na faixa 01-12 e minutos 00-59, separados por dois-pontos.
4. Tempo horas:MM:SS ? aceita qualquer quantidade de horas (0 ou mais, um ou mais dígitos), minutos 00-59 e segundos 00-59, todos separados por dois-pontos.
5. Tempo horas:MM:SS.mili ? similar ao anterior, porém inclui 3 dígitos finais para milisegundos 000-999, separados dos anteriores por ponto (.).


Use o formulário de exemplo ao lado para validar um endereço de e-mail (correio eletrônico).

As expressões regulares utilizadas nesta validação estão apresentadas no quadro a seguir. As expressões estão exibidas em mais de uma linha apenas para melhor legibilidade, mas devem ser consideradas como em uma única linha cada.

reEmail1 = /^[\w!#$%&'*+\/=?^`{|}~-]+(\.[\w!#$%&'*+\/=?^`{|}~-]+)*
reEmail2 = /^[\w-]+(\.[\w-]+)*@(([\w-]{2,63}\.)+[A-Za-z]{2,6}
reEmail3 = /^[\w-]+(\.[\w-]+)*@(([A-Za-z\d][A-Za-z\d-]{0,61}[A-Za-z\d]\.)+

A principal especificação para regras endereço de correio eletrônico (e-mail) é o padrão Internet RFC 2822: Internet Message Format, seção 3.4.1 sobre especificação de endereços. Basicamente, o endereço segue a forma nome-local@domínio, onde nome-local especifica o usuário, e domínio especifica o seu endereço ou servidor.

As regras de nome-local são definidas de forma muito ampla na RFC 2822 e portanto são bastante dependentes de restrições específicas adotadas por cada servidor de domínio e tecnologia implementada. Pela especificação, um nome pode ser uma ou mais "palavras atômicas" sem espaço, contendo caracteres dentre letras (maiúsculas/minúsculas), dígitos (0-9) e os símbolos ! # $ % & ' * + - / = ? ^ ` { | } ~; as palavras são separadas entre si por ponto (.).

Um domínio pode ser especificado por nome ou por número IP. O nome de domínio tem a sintaxe geral subdomínio(s).nome-principal.TLD. Subdomínio(s), separados por ponto, são opcionais. Os terminadores de domínio ? conhecidos como domínio primário, nível-raiz, nível-topo ou simplesmente pela sigla TLD (Top-Level Domain) ? são definidos pelo organismo internacional Internet Assigned Number Authority (IANA) e podem ser:

* Genérico (gTLD): .aero, .biz, .com, .coop, .info, .museum, .name, .net, .org, .pro, .gov, .edu, .mil, .int;
* Código de País (CCTLD): uma sigla de duas letras que especifica um país;
* Infra-estrutura: .arpa, de uso restrito (ARPA = Address and Routing Parameter Area).

As regras de nome de domínio principal variam de país para país; a grande maioria aceita de 2 a 63 caracteres, que podem ser letras, algarismos ou o hífen (desde que este não seja nem o primeiro nem o último caractere), segundo a recomendação de sintaxe especificada nas RFC 1034 (3.5) e RFC 1035 (2.3.1). Não é considerada diferenciação entre letras maiúsculas e minúsculas. Navegadores Internet antigos podem ter problema em reconhecer nomes de domínio com mais de 26 caracteres; por isso, vários países (inclusive o Brasil) limitam nomes a este tamanho. Com algumas restrições, podem ser aceitos nomes com caracteres internacionais (acentuados, Unicode etc.).

Na especificação de um domínio no endereço de e-mail, também pode ser aceito um número IP diretamente, entre colchetes, na forma [n1.n2.n3.n4] onde n1 a n4 são números entre 0 e 255.

As especificações e regras para endereços de correio eletrônico e nomes de domínio são amplas, imprecisas e cheias de situações específicas, de forma que uma expressão regular de validação pode ser desde muito flexível até bastante restritiva, conforme a necessidade.

Nos exemplos de expressão regular acima, temos:

1. Livre ? ReEmail1 aceita nome-local com todos os caracteres permitidos na RFC 2822: [\w!#$%&'*+/=?^`{|}~-]; e o domínio tem definição bem livre, por nome basicamente fixando apenas que o TLD deve ter entre 2 e 6 caracteres: [A-Za-z]{2,6}; ou por número IP entre colchetes: \[\d{1,3}(\.\d{1,3}){3}\].
2. Compacto ? ReEmail2 limita os caracteres permitidos no nome-local de forma mais compacta e restritiva, porém cobre os casos mais comuns. Aceita como nome-local uma ou mais palavras separadas por ponto ([\w-]+(\.[\w-]+)*), onde cada palavra é definida por [\w-]+ permitindo assim letra, dígito, sublinhado e hífen. Também limita o tamanho de nomes de domínio entre 2 e 63 caracteres apenas com letras, dígitos, sublinhado e hífen: [\w-]{2,63}.
3. Restrito ? ReEmail3 é uma variação da ReEmail2, mas força nomes de domínio entre 2 e 63 caracteres, deixa de usar a seqüência \w para não permitir o sublinhado e garante que não há hífen nem na primeira nem na última posição, conforme RFC 1034/1035. O resultado é o seguinte para representar um nome de domínio: [A-Za-z\d][A-Za-z\d-]{0,61}[A-Za-z\d].

Uma última dica: para os domínios como número IP, foram usadas seqüências de 1 a 3 dígitos (\d{1,3}) para cada um dos 4 números componentes do IP. Para validar precisamente cada número entre 0 e 255, o padrão de expressão regular poderia ser ([01]?\d?\d|2[0-4]\d|25[0-5]). Fica como "exercício" para o leitor construir uma expressão que represente um TLD apenas de duas letras (país), ou um dos TLDs genéricos ou de infra-estrutura atualmente existentes.
Função de Validação

Escolhida a expressão regular mais adequada para a validação de certo tipo de dado, criar uma função JavaScript de validação para esse tipo fica trivial assim:

function isTipo(pVal)
var reTipo = /^...$/; // Onde ... é a expressão regular apropriada
return reTipo.test(pVal);

Considerações finais

É importante ressaltar que a validação de formulários que são submetidos ao servidor web jamais deve depender apenas de JavaScript no lado cliente, pois não se pode assegurar que o recurso esteja ativado e funcionando corretamente em todos os navegadores utilizados no acesso. Implementada ou não uma validação em JavaScript, deve sempre haver uma validação dos dados recebidos no servidor de aplicação. O uso de validação via JavaScript cliente serve essencialmente como um facilitador para pré-validação no lado cliente, possibilitando que o usuário tenha seus dados verificados ainda antes de submeter o formulário, evitando assim ter de aguardar o processamento pelo servidor para só então ser informado de que eventualmente errou algo e deve corrigir.

Expressão regular é um recurso também disponível em linguagens utilizadas em servidores de aplicação web, como Java, ASP.NET, PHP, Perl e outras, de forma que essa técnica pode ser usada analogamente para validação no lado servidor, observadas as diferenças de sintaxe e implementação de expressão regular em cada linguagem.

Além da validação de máscaras/formatos de texto como visto aqui, expressões regulares são também muito úteis na própria aplicação ou remoção de máscaras e formatação de texto. Veja um exemplo disto no artigo sobre Tratamento de CPF e CNPJ em JavaScript.
Tratamento de CPF e CNPJ

quarta-feira, março 01, 2006

quarta-feira, fevereiro 22, 2006

Apresentando JTri

Apresentando JTri
(another java application generator)

Enviada por Carlos Eduardo em Quarta-Feira, 22 de Fevereiro de 2006

A algum tempo acompanhamos o desenvolvimento do JTri que nada mais é que um projeto de software livre para acelerar o desenvolvimento de aplicações java para a "web". O projeto é bem interessante e está se desenvolvendo muito bem.

Java.tri é um projeto de software livre para acelerar o desenvolvimento de aplicações java para a "web". É dividido em duas partes principais:

O "java.tri Tools" é um conjunto de programas plugaveis em eclipse para importar modelos UML, projetar aplicações utilizando especificações extensiveis de alto nível e gerar código ou até mesmo a aplicação interia. Utilizando moldes velocity e a tecnologia JMerge, pode-se gerar código sem apagar alterações manuais do código.

O "java.tri Framework" é um conjunto de classes construidas sobre o struts e o hibernate para realizar tarefas comuns em aplicações "web" como iterar em paginas de dados, mostrar lista de valores para escolha, caixas de escolhas alimentadas por dados persistentes, coordenação mestre-detalhe, telas de filtro para realizar buscas e outras funcionalidades.

O projeto java.tri está em um estágio inicial de desenvolvimento e aceita constribuições. Precisa-se de desenvolvedores, documentadores, testadores beta, etc.

Mais informações: http://www.jtri.com.br/pt/index.html


Link Permanente: http://www.javafree.org/news/view.jf?idNew=2742

JAG - Java Application Generator

JAG - Java Application Generator: "JAG - Java Application Generator

JAG is an application that creates complete, working J2EE applications. It is intended to alleviate much of the repetitive work involved in creating such applications, while providing a means of quality assurance that the applications created will be of consistent quality. "

terça-feira, fevereiro 21, 2006

Moyosoft - Java Outlook Connector

Moyosoft - Java Outlook Connector: "Java Outlook Connector

Java Outlook Connector (JOC) is a Java library built to access the MS Outlook application. This library is intuitive and easy to use. All the underlying complexities (JNI, COM) are hidden to the Java developer."

segunda-feira, fevereiro 20, 2006

Portable Firefox Support | PortableApps.com

Portable Firefox Support | PortableApps.com

vc conhece a extensão "portable firefox"? você faz uma cópia do firefox em um pen drive e copia todas as configurações pessoais do pc da sua casa para a cópia do pen drive. então qdo vc estiver navegando em outro lugar, basta espetar o pen drive e abrir o mesmo firefox que vc usa em casa, com todos as extensões e plugins.

sexta-feira, fevereiro 17, 2006

DVD Burners and Decrypters


Easy DVD Clone 3.0.3 - http://www.homedvdcopy.com/
Clone DVD http://www.consumerfirstreviews.com/reviews/clonedvd_dvdxstudios.html?page_id=7&form_keyword=dvd+writers&rd=1
DVDXPlatinum - http://www.best-dvd-burning-software-reviews.com/dvd-burning.asp?n=2


DVD Decrypter v3.5.4.0 - (Parece q não tem mais)
DVDFab Decrypter (free DVD ripper) - http://www.afterdawn.com/software/video_software/dvd_rippers/dvdfab_decrypter.cfm
AnyDVD v5.6.3.1 - http://www.afterdawn.com/software/video_software/dvd_rippers/anydvd.cfm
ImgBurn v1.1.0 - http://www.afterdawn.com/software/cdr_software/cdr_tools/imgburn.cfm

quinta-feira, fevereiro 16, 2006

Assinatura de Applets :: Java Free.org

O modelo de segurança implementado pela plataforma Java, na sua proposição inicial, é centrada sobro o conceito de sandbox (caixa de areia) (4). De acordo com o modelo sandbox, um código remoto (applet) não é confiável e pode acessar recursos limitados, fornecidos dentro do sandbox, uma área do Servidor Web dedicado àquele applet. A idéia de sandbox foi desenvolvida no sentido de garantir que mesmo que um usuário carregue um applet malicioso, esse não pode danificar a máquina local, por exemplo, apagar um arquivo do seu disco local.

Porém existem applets que são de confiança e necessitam s air do sandbox para fornecer um determinado serviço. Existem varias maneiras para resolver este problema, uma delas é a assinatura do applet. (4)

O JDK 1.1.x introduziu o conceito de applet assinado. Neste modelo estendido, um applet assinado digitalmente é tratado como código local confiável (aplicação standalone) se a assinatura é reconhecida como confiável pelo sistema que recebeu o applet. Entretanto no JDK 1.2.x, o applet assinado terá liberdades conforme especificado por um arquivo de política (policy file). Utilizou-se neste trabalho para o processo de assinatura e verificação do Applet Cliente a versão JDK 1.2.1.

Assinatura digital é utilizada quando se necessita da certeza da origem de uma mensagem como se fosse uma assinatura escrita no papel. Para assinar um applet, o desenvolvedor empacota todo o código Java e arquivos relacionados dentro de um arquivo JAR (Java ARchive) (2), que é um formato de arquivo de compactação de propósito geral, usado para compactar os componentes de uma aplicação Java. A plataforma Java assina e verifica arquivos JAR usando um par de chaves (chave pública e chave privada). A chave privada funciona como uma "caneta" eletrônica que assina o arquivo (ver Figura 1). Como o próprio nome sugere, esta chave só é conhecida pelo assinante do applet. O processo de verificação da assinatura pode ser feito por qualquer pessoa que possua a chave pública correspondente a chave que assinou o arquivo.(1)


[size=9:1f763170b3]Figura 1 ? Processo de assinatura[/size:1f763170b3]

A chave pública é distribuída dentro de um certificado que é uma declaração assinada por uma entidade idônea, chamada Autoridade de Certificação (Certification Authority- CA), que confirma que a chave pública que está no mesmo é confiável. Existem várias Autoridades de Certificação, por exemplo, a VeriSign, Thawte, Entrust e Certisign (empresa brasileira). Toda CA requer um emissor para validar a sua identidade, até mesmo a de mais alto nível. Para estes casos, existem os certificados auto-assinados (self-signed), onde o emissor do certificado é o próprio sujeito.

Os browsers Netscape e Internet Explorer (IE) não usam a codificação de assinatura do JDK. Existem basicamente três tipos diferentes de assinatura de applets, para o IE, para o Netscape, e para o plug-in Java da Sun. Este último fornece aos browsers citados acima a capacidade de utilizar applets assinados através da Java Security API do kit JDK.

Algumas ferramentas necessárias para a assinatura, seguindo o padrão da Sun, encontram-se no JDK 1.2, são elas (7):

Jar (JAR Creation Tool)
Keytool (Key and Certificate Management Tool)
Jarsigner (JAR Signing and Verification Tool)
PolicyTool (Policy File Creation and Management Tool)
Para uma melhor compreensão, encontra-se descritos a seguir os passos utilizados no processo de assinatura e verificação do AppletClient.

Passos para assinar um Applet
Os passos para assinar um Applet estão representados na Figura 2:

[size=9:1f763170b3]Figura 2 ? Diagrama de blocos do processo de assinatura por parte do desenvolvedor [/size:1f763170b3]

Criar o arquivo JAR (2)Deve-se criar um arquivo JAR contendo o arquivo .class da Applet e todas as classes que serão utilizadas e que farão uso de recursos fora do sandbox conforme indicado no item 1 da Figura 2. É importante ressaltar que a ferramenta jarsigner somente assinará arquivos JAR criados pelo JDK, ou arquivos ZIP.

Uma ferramenta utilizada para criação deste arquivo é o jar do JDK. Para criar um JAR contendo o arquivo MeuApplet.class, com o nome MeuJar.jar basta fazer:

jar cvf MeuJar.jar MeuApplet.class  

Utilizou-se a opção "exportar para arquivo JAR" do Visual Age (ambiente de desenvolvimento Java da IBM) para empacotar os arquivos necessários.

Gerar o par de chaves (pública e privada) (5)

Este passo deve ser executado se ainda não houver um par de chaves a ser usado no processo de assinatura (ver item 2 da Figura 2). Para criar o par de chaves utiliza-se a ferramenta keytool do JDK cujas opções são:

Keytool -genkey {-alias alias} {-keyalg keyalg} {-keysize keysize} {-sigalg sigalg} {-dname dname} {-keypass keypass} {-validity valDays} {-storetype storetype} {-keystore keystore} {-storepass storepass} {-v} {-Jjavaoption}  

alias þ Nome pelo qual as chaves serão reconhecidas e armazenadas no keystore (banco de chaves). Ex: mykey
keyalg þAlgoritmo de criptografia utilizado para a criação das chaves. Este argumento é opcional, se nada for especificado o algoritmo utilizado será o DSA (Digital Signature Algorithm). Neste projeto foi utilizada esta opção default.
keysize þ Tamanho da chave que será gerada. O algoritmo DSA suporta tamanhos de 512 a 1024 bits, sendo o tamanho necessariamente múltiplo de 64. Para qualquer algoritmo o tamanho default é 1024.
sigalg þAlgoritmo de criptografia utilizado para assinar o JAR. Este argumento é opcional, se nada for especificado o algoritmo utilizado será o DSA.
dname þ Nome da entidade que gerará o par de chaves Ex:
CN=Banco do DAS, OU=LCMI, O=UFSC, L=Florianópolis, S=Santa Catarina, C=BR
Onde : CN = nome comum, OU = unidade organizacional (departamento, divisão), O = nome da organização, L = nome da localidade (cidade), S = estado, C = código do país.
keypass þ Senha utilizada para a proteção da chave no keystore.
validity þ Número de dias que o certificado deve ser válido.
storetype þ Permite definir a forma de armazenamento e o formato dos dados do keystore. Por default o formato é JKS (tipo proprietário da implementação de keystore fornecido pela Sun).
keystore þkeystore onde as chaves serão armazenadas. Se nada for especificado serão armazenadas no User.Home\.keystore (em geral c:\windows\.keystore), se não existir este será criado.
storepass þ Senha protetora do keystore.
v þ Mostra o certificado em forma legível  

Para a criação das chaves empregadas neste projeto utilizou-se a seguinte linha de comando:

keytool -genkey -dname "cn=Banco do Das, ou=LCMI, o=UFSC, c=BR" -alias key -keystore u:\grupo\mykeystore -storepass 123456 -validity 180  

Quando as chaves são geradas (comando ?genkey) um certificado auto-assinado é criado. Caso deseje-se trocar este certificado por um certificado reconhecido por uma empresa confiável, deve-se fazer um pedido de certificado de assinatura (CSR CerticateSigning Request), e o resultado desta solicitação deve ser importado para o keystore.

Assinar o arquivo JAR (4)

Deve-se assinar o arquivo JAR com a chave privada, para isto utiliza-se a ferramenta jarsigner do JDK, conforme esquematizado no item 3 da Figura 2, da seguinte forma:

jarsigner [options] jar-file alias  

Onde o jar-file é o arquivo a ser assinado, e o alias, é o nome com o qual a chave privada foi guardada no keystore. As opções são as seguintes:

jarsigner {-keystore url} {-storetype storetype} {-storepass storepass} {-keypass keypass} {-sigfile sigfile} {-signedjar signedjar} {-verbose} {-Jjavaoption}  

keystore þ URL do keystore onde a chave está armazenada. Se nada for especificado serão armazenadas no User.Home\.keystore (em geral c:\windows\.keystore).
storetype þ especifica o tipo do keystore que será instanciado. O tipo default do keystore é especificado pelo valor da propriedade de "keystore.type", no arquivo de propriedades de segurança.
storepass þSenha protetora do keystore. Se não for informada, o programa perguntará antes de assinar.
keypass þ Senha protetora da chave privada. Se não for informada, o programa perguntará antes de assinar.
sigfile þ Especifica o nome a ser usado nos arquivos .SF (arquivo de assinatura) e .DSA (bloco de assinatura).Se nada for especificado, o nome será os 8 primeiros caracteres do alias especificado, se o alias tiver menos que 8, seu nome inteiro será colocado.
signedjar þ Especifica o nome e o local de armazenamento do arquivo JAR assinado. Por default, o arquivo assinado irá sobrescrever o não assinado.
verbose þ Indica o modo verbose, que faz aparecer mais informações na tela durante o processo de assinatura.
A linha de comando utilizada neste projeto foi:

jarsigner -keystore u:\grupo\mykeystore -storepass 123456 -signedjar asistemaBancario.jar sistemaBancario.jar key  

Exportar o Certificado da chave pública (5)

Para que se possa distribuir a chave pública é necessário um certificado autenticando a mesma, deve-se exportar o certificado que está no keystore usando a ferramenta keytool do JDK (ver item 4 Figura 2).

keytool -export {-alias alias} {-file cert_file} {-storetype storetype} {-keystore keystore} {-storepass storepass} {-rfc} {-v} {Jjavaoption}  

alias þ Nome com o qual a chave foi guardada no keystore.
file þLocal e nome com o qual o certificado será exportado.
storetype þ Especifica o tipo do keystore que será instanciado. O tipo default do keystore é especificado pelo valor da propriedade de "keystore.type", no arquivo de propriedades de segurança.
keystore þ Local do keystore onde o certificado está armazenado. Se nada for especificado serão exportadas do User.Home\.keystore (em geral c:\windows\.keystore).
storepass þSenha protetora do keystore. Se não for informada o programa perguntará antes de exportar.
rfc þ Exporta o certificado na forma definida pelo padrão Internet RFC 1421. Quando exportado desta forma este começa com"-------Begin" e termina por "------End".
v þ Indica o modo verbose, que faz aparecer mais informações na tela enquanto exporta o certificado.  

Neste projeto utilizou-se a seguinte linha de comando:

keytool -export -keystore u:\grupo\mykeystore -alias key -file keycert.x509  

O certificado exportado deve ser enviado para os usuários do applet.

Criar a página HTML ( 8 )

Conforme demonstrado no item 5 da Figura 2, para o Applet funcionar nos browser Netscape e IE, é necessário instalar o Plug-in, fornecido pela Sun, e converter a página HTML para que esta informe qual JVM (Java Virtual Machine) será utilizada.

Para fazer a página com suporte a Plug-in basta utilizar a ferramenta HTMLConverter também fornecida pela Sun. Porém, é necessário que uma página previamente pronta, contenha a informação de que um arquivo assinado será utilizado. A Tag deve ser:

<applet quote="Applet.class" ARCHIVE="arquivoAssinado.jar" wdth=500 height=50>

Note que isto é apenas a Tag do applet, a página HTML pode conter outros dados.

Se o applet for rodar no appletviewer, não é preciso converter a página pois o plug-in só é necessário nos browsers.

Passos para verificar a assinatura
Os passos que o usuário deve seguir estão representados na Figura 3:


Instalar Plug-in ( 8 )
Para que o Applet funcione é indispensável que o usuário instale em seu browser a ultima versão do Java Plug-in, fornecido pela Sun (ver item 1 da Figura 3).

Importar o Certificado (5)
Segundo apresentado no item 2 da Fifura 3, o usuário deve importar o certificado enviado pelo desenvolvedor do applet para um keystore de seu disco local, utilizando a ferramenta keytool do JDK.

keytool -import {-alias alias} {-file file}  

alias þ nome com o qual o certificado será importado.
file þ local e nome do certificado.  

Este passo pode ser facilitado pelo desenvolvedor da aplicação se este fornecer o arquivo .keystore, sendo apenas necessário gravá-lo no user.home. Porém, se o usuário deseja ter outros certificados além do fornecido pelo desenvolvedor, este terá que importá-lo, não esquecendo de informar que ele é trusted quando a ferramenta keytool perguntar.

Configurar o Arquivo Policy
Como último passo (ver item 3 Figura 3), tem-se a configuração do arquivo de política no disco local do usuário da aplicação. Este arquivo informa quais permissões serão atribuídas para as aplicações especificadas. O arquivo policy, pode ser escrito em um arquivo de texto normal, pode ser gerado utilizando a ferramenta policytool do JDK1.2.x., ou ainda pode ser fornecido pelo desenvolvedor da aplicação.

Quando fornecido pelo desenvolvedor, o arquivo policy conterá apenas as permissões da aplicação e deverá ser gravado no user.home\.java.policy. Caso o usuário deseje definir permissões para outras aplicações, este deverá configurá-las no seu arquivo policy.

Neste trabalho utilizou-se a ferramenta policytool, onde o desenvolvedor definiu as permissões necessária para o AppletClient se conectar ao Serviço de Nomes e ao Servidor Bancário e forneceu o arquivo policy gerado ao usuário da aplicação.

Utilizando a Ferramenta policytool (6)
A Figura 4 apresenta a tela inicial do policytool, se estiver sendo usado pela primeira vez, este avisará que nenhum arquivo de política foi encontrado.

[size=9:1f763170b3]Figura 4 ? Tela inicial do aplicativo Policytool [/size:1f763170b3]

Para o usuário criar um novo arquivo, este deve ir no menu File e selecionar New, ou se quiser modificar um arquivo já existente, deve selecionar Open (no mesmo menu) e então escolher o arquivo.

Em seguida deve-se indicar qual keystore será usado. Selecionando o comando Change Keystore no menu Edit, a tela apresentada na Figura 5 solicitará a URL do local onde keystore está armazenado, por exemplo, file:/c:/windows/.keystore, e o tipo de arquivo deste keystore (não sendo necessário preencher, se o tipo for JKS-formato padrão da Sun). Terminada a operação pressiona-se o botão OK.

[size=9:1f763170b3]Figura 5 ? Tela de modificação do keystore do aplicativo Policytool[/size:1f763170b3]

Para adicionar as permissões que possibilitará ao Applet sair do sandbox, pressiona-se o botão Add Policy Entry (Figura 4). Surge então uma nova tela (ver Figura 6), solicitando o preenchimento do quoteBase com a URL do arquivo JAR assinado, se vários arquivos de uma pasta forem usados pode-se colocar um * ao invés do nome do arquivo JAR. E, o campo do SignedBy deve ser preenchido com o alias do certificado da chave que assinou o arquivo.

[size=9:1f763170b3]Figura 6 - Tela do aplicativo Policytool de apresentação das permissões concedidas ao applet[/size:1f763170b3]

Feitas estas operações, deve-se adicionar a permissão para o applet, pressionado o botão Add Permision da Figura 6. A tela da Figura 7 aparecerá, para que se escolha a permissão que será dada. Suponhamos que o Applet tenha que abrir uma conexão (Socket) com outra máquina, a permissão então será java.net.SocketPermission. No Target name pode-se permitir fazer um socket com qualquer outra máquina colocando um * ou especificar uma máquina. Em Actions deve-se escolher quais ações deseja-se permitir (connect, accept, resolve, listen).

[size=9:1f763170b3]Figura 7 - Tela para adicionar permissão do aplicativo Policytool[/size:1f763170b3]

Ao terminar pressiona-se o botão OK, depois Done (ver Figura 6), e salva-se o arquivo selecionando o menu File e depois Save (ver Figura 4).

Note que o Browser procurará pelo arquivo user.home\.java.policy para verificar as permissões de uma aplicação. Portanto, se o usuário do applet deseja que o arquivo policy criado seja utilizado, deve gravá-lo neste local.

Conclusões e Resultados
A implementação utilizando o plug-in Java da Sun demonstrou-se muito útil, pois pode ser utilizado nos browsers mais conhecidos, Netscape e Internet Explorer (IE) , ao passo que sem o plug-in, as assinaturas utilizando o Netscape ou Internet Explorer, por não usarem a codificação de assinatura do JDK, não são compatíveis resultando no não funcionamento do applet em ambos os browsers.

Em contrapartida, para que o processo seja concluído com sucesso, o usuário deve estar ciente que deve utilizar um arquivo policy e também possuir um keystore o que implica ter conhecimento sobre as ferramentas policytool, e keytool se desejar permitir acesso fora do sandbox para applets diferentes.

Demonstrado que esta forma de implementação de assinatura apresenta os resultados desejados, possibilitando todos os acessos necessários fora do sandbox.

(1) OAKS, Scott, Segurança de dados em JAVA, Editora Ciência Moderna Ltda, Rio de Janeiro, 1999.

(2) Sun Microsystems Inc., JAR Guide. Sun Microsystems Inc. Moutain View, CA.
( http://java.sun.com/products/jdk/1.2/docs/guide/jar/jarGuide.html )

(3) Sun Microsystems Inc., jarsigner ? JAR Signing and Verification Tool. Sun Microsystems Inc. Moutain View, CA, October 1998.
( http://java.sun.com/products/jdk/1.2/docs/tooldocs/win32/jarsigner.html

(4) Sun Microsystems Inc., Java Security Architecture (JDK1.2) Version 1.0. Sun Microsystems Inc. Moutain View, CA, October 1998.
( http://java.sun.com/products/jdk/1.2/docs/guide/security/spec/security-spec.doc.html )

(5) Sun Microsystems Inc., keytool - Key and Certificate Management Tool. Sun Microsystems Inc. Moutain View, CA, October 1998.
( http://java.sun.com/products/jdk/1.2/docs/tooldocs/win32/keytool.html )
(6) Sun Microsystems Inc.,Policy Tool - Policy File Creation and Management Tool. Sun Microsystems Inc. Moutain View, CA, October 1998.

(7) Sun Microsystems Inc., Summary of JDK 1.2 Security Tools. Sun Microsystems Inc. Moutain View, CA, October 1998.
( http://java.sun.com/products/jdk/1.2/docs/guide/security/SecurityToolsSummary.html )

( 8 ) Sun Microsystems Inc., JDK 1.2 - Signed Applet Example. Sun Microsystems Inc. Moutain View, CA, February 1999.
( http://java.sun.com/security/signExample12 )  

Luís Carlos Moreira