(Property)MessageResources proposed changes.

2000-12-20 Thread Johan Compagner

Hi,

( i am trying to subscribe to STRUTS-DEV but i don't get a confirmation message so i 
post it first here)

When the new MessageResources class (and its sub) where introduced my app didn't 
work anymore because of the changed behaviour in loading resouces.

I have 2 fixes that i have attached here:

First is the MessageResources.localeKey(Locale) method that is needed by both
PropertyMessageResources that i send in.

this:
protected String localeKey(Locale locale) {
if (locale == null)
return ("");
else if (locale.equals(defaultLocale))
return ("");
else
return (locale.toString());
}
is changed to this:
protected String localeKey(Locale locale) {
if (locale == null)
return ("");
else
return (locale.toString());
}

Because when it is the default locale or not that doesn't matter. First it must try to
load the right resources for the default locale.
For example if the default locale is nl_NL then i want it to try to load:
xxx.nl_NL.properties or xxx.nl.properties before it tries to load xxx.properties.
Because maybe now my webapp is on a system there the default locale is nl_NL
but maybe it's also getting deployed on a system with the default locale en_US.
Then suddenly the struts load the wrong properties file for the locale, 
(What must be the xxx.properties file? English or Dutch?)
ResourceBundle it self does also try to load the nl_NL first it doesn't look
if the given locale is the default one or not.

PropertyMessageResources.getMessage(Locale,String) changes:

this piece of code:

 // As a last resort, try the default Locale
 localeKey = localeKey(defaultLocale);
 messageKey = messageKey(localeKey, key);
 loadLocale(localeKey);
 synchronized (messages)
{
  message = (String) messages.get(messageKey);
  if (message != null)
  {
   if (addIt)
messages.put(originalKey, message);
   return (message);
  }
 }

is changed to this:

 // try the default Locale if current locale isn't default
 if(locale != defaultLocale)
 {
  localeKey = localeKey(defaultLocale);
  messageKey = messageKey(localeKey, key);
  loadLocale(localeKey);
  synchronized (messages)
  {
   message = (String) messages.get(messageKey);
   if (message != null)
   {
if (addIt)
 messages.put(originalKey, message);
return (message);
   }
  }
 }

 // last resort: try loading de base
 localeKey = "";
 messageKey = messageKey(localeKey, key);
 loadLocale(localeKey);
 synchronized (messages)
 {
  message = (String) messages.get(messageKey);
  if (message != null)
  {
   if (addIt)
messages.put(originalKey, message);
   return (message);
  }
 }

So i my last resort isn't trying to get it with the defaultLocale
I test it first (maybe equals should be used in tead of == ) 
so that the loading and the synchronized lock isn't invane.

After that and still the message isn't returned i go to my last resort
and that is loading the base (xxx.properties)

But i thought why implement the exact same behaviour of the ResouceBundle?
So i made my own class.

Here are the 2 methods:
public String getMessage(java.util.Locale locale, String key) {
 if(locale == null) locale = defaultLocale;
 String localeKey = localeKey(locale);
 String messageKey = messageKey(localeKey, key);
 String message = null;
 // first try to load a previous stored resource.
 synchronized (messages) {
  message = (String) messages.get(messageKey);
 }
 // if there was no previous stored resource.
 if(message == null) { 
  // try loading the resources
  loadMessages(locale);
  // try getting it again.
  synchronized (messages)  {
   message = (String) messages.get(messageKey);
  }
 }
 // If still null.
 if(message == null) {
  // Return an appropriate error indication
  if (returnNull)  return (null);
  else return ("???" + messageKey(locale, key) + "???");
 }
 return message;
}

protected void loadMessages(Locale locale) {
 String localeKey = localeKey(locale);
  // Have we already attempted to load messages for this locale?
 synchronized (locales) {
  if (locales.get(localeKey) != null) return;
  locales.put(localeKey, localeKey);
 }

 ResourceBundle bundle = 
java.util.ResourceBundle.getBundle(config,locale,this.getClass().getClassLoader());

 if(bundle != null) {
  synchronized (messages) {
   Enumeration names = bundle.getKeys();
   while (names.hasMoreElements())  {
String key = (String) names.nextElement();
messages.put(messageKey(localeKey, key), bundle.getObject(key));
   }
  }
  }
 }

I use the resoucebundle class to get the properties.
This has the following advantages:

1 Not having to implement and maintain the complete reading in code.
2 support for not only resource property files but also resource class files!!
3 No double keys for all the resouces when given locale = nl_NL and the properties 
file = xx_nl.properties

explain 3:
Locale = nl_NL
propertie file = xxx._nl.properties
first messages aren't found for that locale key. 

Re: Bad Multi-Threading Performance

2000-12-20 Thread Ned Seagoon

From: Matthew Strayer [EMAIL PROTECTED]

The situation you describe does not cause deadlock because the wait()
call in thread
2 releases the synchronized lock.

Ahh - didn't realise that! It's not been in any docs I've read before. Now, 
i've found it buried now in 4 lines of page 184 of Concurrent programming in 
Java.

The only way I can think of to alleviate this problem is use different
synchronization primitives.  Unfortunately, Java
doesn't have them.  And all libraries that simulate these use
synchronization!

heheheh - hooray for Java :-)

Now, maybe someone here could hack some byte code
(does Java have a set-and-test instruction??) and
produce them... ;-)

Trouble is with a test and set is it atomic? I would imagine why the lack of 
better sync options and test  set options plus say a version of interlocked 
increment is perhaps due to the 'lowest common denominator' basis of java.

Regards
Ned

_
Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com.




Proposal: RetroFit Struts with the Delegation Event Model

2000-12-20 Thread David Geary

ABSTRACT

It's often convenient, and sometimes necessary, to handle Struts events,
such as when an action has its locale set, or when the action servlet
processes an action's form. This document proposes retrofitting Struts 
with the delegation event model. That model, which is used by the AWT
and
Swing, makes event handling simple, flexible, and scalable.


CREDITS

Delegation and Event Model for Struts? -- posted to struts-dev by 
  Robert Leland

INTRODUCTION

Currently, you can use inheritance to handle Struts events like those 
described above. Typically, that means extending ActionServlet and 
overriding a protected method, such as
ActionServlet.processActionPerform.

Inheritance-based event handling is inflexible and does not scale well
because event sources and listeners are tightly coupled at compile time.
This was evident to AWT engineers, who replaced the AWT's original
inheritance-based event model with the delegation event model.

The delegation event model, which has its roots in java.util, implements
the Observer design pattern to loosely couple event sources and event
listeners at runtime. That loose coupling makes it easy to associate
disparate types of objects, so that event listeners can easily react to
changes in event sources.


STRUTS AND THE DELEGATION EVENT MODEL

So what does it mean to retrofit Struts with the delegation event model?
It means that Struts will fire events when it performs certain 
functions. You can register with Struts as an event listener, and 
handle events as you see fit.

This proposal advocates firing events for all interesting Struts
functions; for example, the action servlet should fire a robust set of
events for processing actions and forms, performing mappings, etc. 
Implementing support for those events follows the same
design pattern discussed in this proposal for implementing action
events.

This proposal illustrates how to modify Struts to fire events just
before, and immediately after, a Struts action has its perform method
invoked. Those events are hereafter known as action events.


IMPLEMENTING ACTION EVENTS AND ACTION LISTENERS

Getting Struts to fire action events is easy. First, we define a
listener interface and an event class:

org/struts/apache/event/action/ActionListener.java
org/struts/apache/event/action/ActionEvent.java

Here's the listing for ActionListener:

   public interface ActionListener {
  public void beforeActionPerform(ActionEvent event) 
throws ServletException;
  public void afterActionPerform(ActionEvent event)  
throws ServletException;
   }

ActionListener methods are passed instances of ActionEvent. Here's the
listing for that class:

   public class ActionEvent extends java.util.EventObject {
  public static final int BEFORE_ACTION_PERFORM=0,
  AFTER_ACTION_PERFORM=1;
  private int eventType;
  private HttpServletRequest request;
  private HttpServletResponse response;
  public ActionEvent(Action action, int eventType,
 HttpServletRequest request,
 HttpServletResponse response) {
 super(action);  // specifies action as the event source
 this.eventType = eventType;
 this.request   = request;
 this.response  = response;
  }
  public int getEventType() { return eventType; }
  public HttpServletRequest  getRequest()   { return request; }
  public HttpServletResponse getResponse()  { return response; }
   }

Through action events, action listeners have access to:

event type (BEFORE_ACTION_PERFORM, AFTER_ACTION_PERFORM)
action
request
response


HANDLING ACTION EVENTS

Here's how you use action events and listeners:

   // first, implement a listener that handles action events

   public class MyListener implements
   org.apache.struts.event.ActionListener {
  public void beforeActionPerform(ActionEvent event) {
 // handle event
  }
  public void afterActionPerform(ActionEvent event) {
 // handle event
  }
   }

   // Then register your listener with an action:

   someAction.addActionListener(new MyListener());

Thereafter, MyListener.beforeActionPerform and
MyListener.afterActionPerform will be called before and after
someAction's perform method, respectively.

Let's see what changes need to be made to Struts to make this work.


STRUTS MODIFICATIONS FOR SUPPORTING ACTION EVENTS

Only two Struts classes need to be modified to support firing action
events: Action and ActionServlet. Methods are added to the Action class
for registering action listeners and firing events:

   // the following is added to org.apache.struts.action.Action:

   import java.util.Enumeration;
   import java.util.Vector;
   import org.apache.struts.event.action.ActionEvent;
   import org.apache.struts.event.action.ActionListener;

   public class 

Page Forwarding Question

2000-12-20 Thread James Howe

In my action classes I have code which checks to see if a user has logged 
on.  If not, the code forwards to the logon page (e.g. 
servlet.findForward("logon")).  However this doesn't fully accomplish what 
I would like.  If a user attempts to reference a page which requires a 
login, I would like to forward to the login page and, once the user has 
authenticated, proceed back to the page to which the user was going in the 
first place.  In other words, I would like to forward to the logon screen, 
but give it a parameter which it uses to tell it which page follows the 
logon.Can anyone suggest a simple way to accomplish this?

Thanks.




RE: Page Forwarding Question

2000-12-20 Thread Sayles, Scott SAXONHQ

Have the login page write a hidden field with the value of the requested url
and submit it to your logon action.  From your logon action you can then
instantiate a new ActionForward and set the path to the requested url, as
defined in the hidden form field, and return that.  Alternatively, instead
of instantiating a new ActionForward you could just use the request
dispatcher and forward with it and then return a null to the ActionServlet.

I'm using a similar method now but exapanded it so that all request
parameters are written as hidden fields in the login form as well.  That
way, the previous form results can be submitted along with the login request
(and then on to the subsequent page or action).

Hope this helps.

 -Original Message-
 From: James Howe [mailto:[EMAIL PROTECTED]]
 Sent: Wednesday, December 20, 2000 10:06 AM
 To: [EMAIL PROTECTED]
 Subject: Page Forwarding Question
 
 
 In my action classes I have code which checks to see if a 
 user has logged 
 on.  If not, the code forwards to the logon page (e.g. 
 servlet.findForward("logon")).  However this doesn't fully 
 accomplish what 
 I would like.  If a user attempts to reference a page which 
 requires a 
 login, I would like to forward to the login page and, once 
 the user has 
 authenticated, proceed back to the page to which the user was 
 going in the 
 first place.  In other words, I would like to forward to the 
 logon screen, 
 but give it a parameter which it uses to tell it which page 
 follows the 
 logon.Can anyone suggest a simple way to accomplish this?
 
 Thanks.
 



DataSource

2000-12-20 Thread Sayles, Scott SAXONHQ


Pardon me if I'm missing something, but is it intended that the
javax.sql.DataSource be required in the ActionServlet?  It's just that I
downloaded a recent build and I'm now getting errors when trying to compile
my actions.  They relate to javax.sql.DataSource not being found on the
import.  Is it required to have the JDBC 2.0 Standard Extensions API now?

Thanks.



Re: DataSource

2000-12-20 Thread craig mcclanahan

"Sayles, Scott SAXONHQ" wrote:
 
 Pardon me if I'm missing something, but is it intended that the
 javax.sql.DataSource be required in the ActionServlet?  It's just that I
 downloaded a recent build and I'm now getting errors when trying to compile
 my actions.  They relate to javax.sql.DataSource not being found on the
 import.  Is it required to have the JDBC 2.0 Standard Extensions API now?
 
 Thanks.

To compile Struts itself, you will need to download the JDBC 2.0
Standard Extensions JAR file and put it on your classpath.  (I need to
update the README to be more explicit about this.)  If you are just
compiling your own classes, you should not need them, but will again at
runtime (even if you do not use a DataSource in your app.

Craig



Re: What's Struts ...

2000-12-20 Thread craig mcclanahan

Steve A Drake wrote:
 
 On Mon, 19 Jun 2000, Shiraz Wasim Zaidi wrote:
 
  The action's servlet can then handle the request, and return a HTTP response
  to the controller, which the controller can pass back to the client.
 
  ---COMMENT
  I think you have a wrong understanding that action classes are servlets. No
  they are regular java class that implements Action interface and provide
  perform method definition that is the actions business logic.  Moreover
  Action Classes never return response to the controller servlet i.e.
  ActionServlet. They always return ActionForward, which might be null.
 
  Just so we're all on the same page here, according to the
 (0.5) documentation, an Action class is not a servlet but it has a simliar
 lifecycle to a servlet in that only one Action object is instantiated. So,
 you must consider multi-threading issues when coding your Action class
 (like you would with a servlet). Someone please correct me if this is not
 the case.
 

This is correct for all versions of Struts, although in Struts 1.0
Action is a base class that you extend, rather than an interface that
you implement.  In addition, the Action class now receives lifecycle
indications through the call to setServlet() -- a non-null argument
tells you that this Action is about to be invoked for the very first
time, and a null argument tells you that this instance has been taken
out of service (currently, this only happens when the web application is
shut down.)


  JavaBeans can also be used to manage input forms. A key problem in designing
  Web applications is retaining and validating what a user has entered between
  requests. With Struts, you can store the data for a input form in a form
  bean, which is automatically maintained through the user's Struts session.
  ---COMMENT
  Not necessarily. FormBean would be maintained through user's session if the
  formbean has a scope of session.
  ---/COMMENT
 
  And, looking at the processActionForm() method in the ActionServlet
 class, session is the default scope for ActionForm beans.

Session is the default scope; request is the other option.  It makes for
more scalable applications if you can use it, but requires that all of
the properties of your ActionForm bean be included in the page.

Craig McClanahan



RE: Page Forwarding Question

2000-12-20 Thread Shiraz Wasim Zaidi

 In my action classes I have code which checks to see if a user has logged
 on.  If not, the code forwards to the logon page (e.g.
 servlet.findForward("logon")).  However this doesn't fully
 accomplish what
 I would like.  If a user attempts to reference a page which requires a
 login, I would like to forward to the login page and, once the user has
 authenticated, proceed back to the page to which the user was
 going in the
 first place.  In other words, I would like to forward to the
 logon screen,
 but give it a parameter which it uses to tell it which page follows the
 logon.Can anyone suggest a simple way to accomplish this?

I think you might have problem using this approach if the session expires.

Let's say that a user's session expires due to time out and ur referenced
page relies on session data.
User was on Order List screen showing a list of orders. He goes for coffee
comes after an
hr. and session expires. He tries to view next page of Order List and in ur
action or JSP you detect
login required and forward to loginPage with somehow indicating to show
OrderList page after authentication.
Now ur OrderList jsp would be looking for session data to render the view
and it wont find anything as the
session is new.

What do you think?


-Shiraz







Missing message for key index.title

2000-12-20 Thread Neal Kaiser

Can someone tell me what this error means:

javax.servlet.jsp.JspException: Missing message for key index.title at
org.apache.struts.taglib.bean.MessageTag.doStartTag(MessageTag.java:261)

I get it when trying to run the  struts-example on Orion Server.

THanks



RE: Missing message for key index.title

2000-12-20 Thread Neal Kaiser

Thanks. I actually have both of those already. I think it might have to do
with
the Orion Server.  I did take the steps that have been posted in the past to
get it to work with Orion, but still no luck.  Could this be related? In my
orion console I see:

[root@www orion]# Orion/1.4.4 initialized
resolveEntity('-//Apache Software Foundation//DTD Struts Configuration
1.0//EN', 'http://jakarta.apache.org/struts/dtds/struts-config_1_0.dtd')
 Not registered, use system identifier
Parse Error at line 37 column -1: Element "struts-config" does not allow
"form-beans" here.
org.xml.sax.SAXParseException: Element "struts-config" does not allow
"form-beans" here.

and a bunch more errors.

Neal

 -Original Message-
 From: Jason Haase [mailto:[EMAIL PROTECTED]]
 Sent: Wednesday, December 20, 2000 9:22 PM
 To: '[EMAIL PROTECTED]'
 Subject: RE: Missing message for key index.title



 It sounds like your ApplicationResources.properties file is not there.
 Check to make sure it is in
 ...\struts-example\WEB-INF\classes\org\apache\struts\example.
 Orion should
 have unpacked the struts-example.war file for you.  Otherwise,
 look in your
 web.xml file to make sure your "Action Servlet Configuration"
 specifies the
 right properties file.  Like this:

 init-param
   param-nameapplication/param-name

 param-valueorg.apache.struts.example.ApplicationResources/param-value
 /init-param


 Jason Haase



 -Original Message-
 From: Neal Kaiser [mailto:[EMAIL PROTECTED]]
 Sent: Wednesday, December 20, 2000 6:09 PM
 To: [EMAIL PROTECTED]
 Subject: Missing message for key index.title


 Can someone tell me what this error means:

 javax.servlet.jsp.JspException: Missing message for key index.title   at
 org.apache.struts.taglib.bean.MessageTag.doStartTag(MessageTag.java:261)

 I get it when trying to run the  struts-example on Orion Server.

 THanks





RE: What's Struts ...

2000-12-20 Thread Shiraz Wasim Zaidi


an Action class is not a servlet but it has a simliar lifecycle to a
servlet
in that only one Action object is instantiated.
Not always true. If your servlet implements SingleThreadModel interface then
container creates a pool of servlet instances.

  And, looking at the processActionForm() method in the ActionServlet
 class, session is the default scope for ActionForm beans.
Yeah you are correct.

-Shiraz Zaidi




How can I use a java variable that was defined in the enclosing template tag?

2000-12-20 Thread Hay Tran



Here is an example:
// Here is the code segment for the enclosing tag, 
the template:insert ...
.
%
 String strToBeUsedByPageA = 
"Hello";
%

template:insert 
template='aTemplate.jsp'
 template:put 
name='PageA.jsp'
/template:insert


// Here is the code segment for the enclosed file, 
PageA

The enclosing tag defined the strToBeUsedByPageA 
variable that is being displayed here:%=strToBeUsedByPageA 
%
...


// I get the error msg saying 
strToBeUsedByPageA is not define.

Thanks for any help I can get.

-Hay