/*
* This file is part of the WfMOpen project.
* Copyright (C) 2001-2003 Danet GmbH (www.danet.de), GS-AN.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: Mapping.java 1607 2006-09-29 12:32:13Z drmlipp $
*
* $Log$
* Revision 1.1.1.1 2003/06/30 20:05:12 drmlipp
* Initial import
*
* Revision 1.17 2003/06/27 08:51:46 lipp
* Fixed copyright/license information.
*
* Revision 1.16 2003/04/24 20:50:13 lipp
* Fixed some warnings.
*
* Revision 1.15 2003/03/31 16:50:28 huaiyang
* Logging using common-logging.
*
* Revision 1.14 2002/06/10 20:52:45 lipp
* Removed intermediate cocoon2 code.
*
* Revision 1.13 2002/06/08 12:15:29 lipp
* Removed cocoon2 add-ons, now in a new separate class.
*
* Revision 1.12 2002/06/03 11:57:24 huaiyang
* New methods for Cocoon 2 added.
*
* Revision 1.11 2002/04/26 09:03:36 huaiyang
* Correct javadoc error.
*
* Revision 1.10 2002/04/25 16:03:32 huaiyang
* Modify the method of generateMapping using contentHandler of Cocoon.
*
* Revision 1.9 2002/04/17 12:51:28 lipp
* Upgraded to jdom beta 8.
*
* Revision 1.8 2002/04/16 12:10:37 huaiyang
* Add new method of generateMappings using jdom.
*
* Revision 1.7 2002/04/03 12:53:04 lipp
* JavaDoc fixes.
*
* Revision 1.6 2002/02/06 20:43:51 lipp
* Optimized by introducing cache.
*
* Revision 1.5 2002/01/26 19:45:39 lipp
* SegmentedResourceBundle finally replaced by SegmentedMap.
*
* Revision 1.4 2002/01/17 16:41:48 lipp
* Fixed classloader
*
* Revision 1.3 2002/01/11 12:13:14 robert
* cleanup not needed import statements
*
* Revision 1.2 2001/12/04 15:37:07 lipp
* Comment fixed.
*
* Revision 1.1 2001/12/04 08:31:19 lipp
* Class de.danet.an.util.Mapping moved to subpackage web.
*
* Revision 1.3 2001/11/12 16:06:35 montag
* class documentation revised.
*
* Revision 1.2 2001/11/12 15:22:41 montag
* mapping handling for basename changed
*
* Revision 1.1 2001/11/12 14:52:58 montag
* redesign webclients
*/
package de.danet.an.util.web;
import java.util.Locale;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.ResourceBundle;
import javax.servlet.http.HttpSession;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import de.danet.an.util.ResourceBundleAsMap;
import de.danet.an.util.SegmentedMap;
import de.danet.an.util.web.W3CDomUtil;
/**
* Base class, implementing the methods used in logic sheet(s).
* The mathods in this class can be used to support an internationalization
* of texts and error messages in xsp pages.<p>
* Together with the logicsheet <code>mapping.xsl</code>, to use the
* functionality the followng steps must be fullfilled:
* <ul>
* <li>Include the logicsheet <code>mapping.xsl</code> in your own logicsheet
* for processing the xsp page.</li>
* <li> In your logicsheet, include the following match-rules:
* <pre> <xsl:template match="page">
* <page>
* <xsp:logic>
* if (session == null) {
* session = request.getSession (true);
* }
* session.setAttribute ("errorList", new ArrayList (1));
* </xsp:logic>
* <xsl:apply-templates/>
* <xsp:logic>
* xspCurrentNode.appendChild
* (Mapping.createErrorList(session, document));
* </xsp:logic>
* </page>
* </xsl:template>
*
* <xsl:template match="xsp:page">
* <xsp:page>
* <xsl:apply-templates select="@*"/>
* <xsp:structure>
* <xsp:include>
* de.danet.an.util.Mapping
* </xsp:include>
* </xsp:structure>
* <xsl:apply-templates/>
* </xsp:page>
* </xsl:template>
* </pre></li>
* <li>Define an I18n.properties file for your application.</li>
* <li> In your xsp page, you can now use the mapping functionality, e.g.
* <pre><mapping:generate_mappings key="staff.group.list"
* basename="de.danet.an.staffmgmt.webclient.I18n"/>
* </pre></li>
* <li>In your Java classes, where you encapsulate the logic code, you
* can set error texts like this:
* <pre>Mapping.mapError (session, "de.danet.an.staffmgmt.webclient.I18n",
* "error.staff.addGroupOption");
* </pre></li>
* </ul>
*/
public class Mapping {
private static final org.apache.commons.logging.Log logger
= org.apache.commons.logging.LogFactory.getLog(Mapping.class);
private static Map mapMap = new HashMap ();
private static SegmentedMap getMap (String baseName, Locale loc) {
String key = baseName + "@" + loc.toString();
synchronized (mapMap) {
SegmentedMap res = (SegmentedMap)mapMap.get (key);
if (res != null) {
return res;
}
ResourceBundle bundle = ResourceBundle.getBundle
(baseName, Locale.getDefault(),
Thread.currentThread().getContextClassLoader());
res = new SegmentedMap (new ResourceBundleAsMap (bundle));
mapMap.put (key, res);
return res;
}
}
/**
* Generates mapping entries for a given <code>key</code>.
* The mapping entries are taken from a language specific resource file.
* The given segment name is removed from the resulting keys.
* @param session the http session
* @param doc document, handed over by the cocoon framework
* @param baseName file name of resource bundle
* @param segment prefix for selecting the resource segment
* @return Document fragment with mapping nodes
*/
public static DocumentFragment generateMappings(HttpSession session,
Document doc,
String baseName,
String segment) {
// Get new document fragment
DocumentFragment frag = doc.createDocumentFragment();
// Create mapping entries
SegmentedMap map = getMap (baseName, Locale.getDefault());
for (Iterator i = map.keySet (segment).iterator(); i.hasNext();) {
String key = (String)i.next();
Element mapping = doc.createElement("mapping");
// Remove segment name + "." from path
mapping.setAttribute("key", key.substring(segment.length()+1) );
mapping.appendChild(doc.createTextNode ((String)map.get(key)));
frag.appendChild(mapping);
}
return frag;
}
/**
* Returns the i18n text for a given <code>key</code>.
* The text is based on the language settings
* of the user.
* @param session currently not used. May be used to get information
* about the user's locale.
* @param baseName Family name of the resource bundle
* @param key key for the text
* @return translated key, representing the language specific translation
*/
public static String mapText(HttpSession session,
String baseName, String key) {
// get current message mapping setup and map key
SegmentedMap map = getMap (baseName, Locale.getDefault());
return ((String)map.get(key));
}
/**
* Add an error message to the error list.
* @param session the http session.
* @param msg the error message.
*/
public static void addError (HttpSession session, String msg) {
List errs = (List)session.getAttribute ("errorList");
errs.add (msg);
}
/**
* Add the error message referenced by a key to the error list.
* @param session the http session.
* @param baseName Family name of the resource bundle
* @param key the key of the error message.
*/
public static void mapError (HttpSession session,
String baseName, String key) {
List errs = (List)session.getAttribute ("errorList");
errs.add (mapText (session, baseName, key));
}
/**
* Convert the errors accumulated to an XML structure.
* @param session the http session.
* @param doc document, handed over by the cocoon framework.
* @return Document fragment with error list.
*/
public static DocumentFragment createErrorList
(HttpSession session, Document doc) {
// Get new document fragment
DocumentFragment frag = doc.createDocumentFragment();
List errs = (List)session.getAttribute ("errorList");
if (errs.size() == 0) {
return frag;
}
Element listNode = doc.createElement("errors");
W3CDomUtil.appendDialogHint (listNode, null, "list");
for (Iterator i = errs.iterator(); i.hasNext();) {
String s = (String)i.next();
Element el = doc.createElement("error");
el.appendChild(doc.createTextNode(s));
listNode.appendChild (el);
}
frag.appendChild (listNode);
return frag;
}
}