vgritsenko 2003/02/01 19:26:47
Modified: . changes.xml
src/scratchpad/src/org/apache/cocoon/transformation
CastorTransformer.java
lib/local local-libs.txt
Added: lib/optional castor-0.9.4.2-xml.jar
Removed: lib/optional castor-0.9.4-xml.jar
Log:
Fix bug #11861: extend castortransformer to handle collections,
Upgrade castor to 9.4.2 (bug fix release).
Revision Changes Path
1.344 +5 -1 xml-cocoon2/changes.xml
Index: changes.xml
===================================================================
RCS file: /home/cvs/xml-cocoon2/changes.xml,v
retrieving revision 1.343
retrieving revision 1.344
diff -u -r1.343 -r1.344
--- changes.xml 2 Feb 2003 00:57:49 -0000 1.343
+++ changes.xml 2 Feb 2003 03:26:46 -0000 1.344
@@ -40,6 +40,10 @@
</devs>
<release version="@version@" date="@date@">
+ <action dev="VG" type="update" fixes-bug="11861" due-to="Michael Homeijer"
due-to-email="[EMAIL PROTECTED]">
+ Add support for Collection objects to the CastorTransformer.
+ Upgrade to the SAX2 API, improve logging, and use SourceResolver to load
mappings.
+ </action>
<action dev="VG" type="update" fixes-bug="15748" due-to="Upayavira"
due-to-email="[EMAIL PROTECTED]">
Refactor Main class into two classes, Main and CocoonBean. CocoonBean provides
simple
programmatic interface to the Cocoon.
1.6 +140 -163
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/transformation/CastorTransformer.java
Index: CastorTransformer.java
===================================================================
RCS file:
/home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/transformation/CastorTransformer.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- CastorTransformer.java 30 Jan 2003 08:37:35 -0000 1.5
+++ CastorTransformer.java 2 Feb 2003 03:26:47 -0000 1.6
@@ -10,27 +10,32 @@
import org.apache.cocoon.environment.Session;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.xml.IncludeXMLConsumer;
+import org.apache.cocoon.ProcessingException;
+import org.apache.excalibur.source.Source;
import org.exolab.castor.mapping.Mapping;
import org.exolab.castor.mapping.MappingException;
import org.exolab.castor.xml.Marshaller;
-import org.xml.sax.AttributeList;
+import org.exolab.castor.xml.MarshalException;
+import org.exolab.castor.xml.ValidationException;
import org.xml.sax.Attributes;
-import org.xml.sax.HandlerBase;
import org.xml.sax.SAXException;
-import org.xml.sax.helpers.AttributesImpl;
+import org.xml.sax.InputSource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
+import java.util.Collection;
+import java.util.Iterator;
/**
- * Description: Marshals a object from the Sitemap, Session, Request or
- * the Conext into a series of SAX events
+ * Castor transformer marshals a object from the Sitemap, Session, Request or
+ * the Conext into a series of SAX events.
*
- * Configuation: The Castortransformer need to be configured with a
+ * Configuation: The CastorTransformer needs to be configured with a
* default mapping. This mapping is used as long as no other mapping
- * is spezfied as the element
+ * is specified as the element.
*
*<pre>
* <map:transformer name="CastorTransformer"
src="org.apache.cocoon.transformation.CastorTransformer">
@@ -53,210 +58,182 @@
* The Attribut <code>mapping</code> specifys the mapping to be used. If not given
* the default mapping is used
* <pre/>
- * Author <a href="mailto:[EMAIL PROTECTED]">Thorsten Mauch</a>
*
+ * @author <a href="mailto:[EMAIL PROTECTED]">Thorsten Mauch</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]">Vadim Gritsenko</a>
*/
public class CastorTransformer extends AbstractTransformer implements Configurable {
- private static String CASTOR_URI="http://castor.exolab.org/cocoontransfomer";
- private boolean in_castor_element = false;
- final static String CMD_INSERT_BEAN="InsertBean";
- final static String ATTRIB_NAME= "name";
- final static String ATTRIB_SCOPE= "scope";
- final static String VALUE_SITEMAP ="sitemap";
- final static String VALUE_SESSION ="session";
- final static String VALUE_REQUEST ="request";
- final static String VALUE_CONTEXT ="context";
+ private static final String CASTOR_URI =
"http://castor.exolab.org/cocoontransfomer";
+
+ private final static String CMD_INSERT_BEAN = "InsertBean";
+ private final static String ATTRIB_NAME = "name";
+ private final static String ATTRIB_SCOPE = "scope";
+ private final static String SCOPE_SITEMAP = "sitemap";
+ private final static String SCOPE_SESSION = "session";
+ private final static String SCOPE_REQUEST = "request";
+ private final static String SCOPE_CONTEXT = "context";
+ private final static String ATTRIB_MAPPING = "mapping";
- final static String MAPPING_CONFIG ="mapping";
- private final static String FILE_PREFIX="file:";
+ // Stores all used mappings in the static cache
+ private static HashMap mappings;
- private HandlerBase CastorEventAdapter;
private Map objectModel;
- // stores all used mappings in the cache
- private static HashMap mappingCache;
- private String defaultmapping="castor/mapping.xml";
private SourceResolver resolver;
- public CastorTransformer() {
+ private String defaultMappingName;
+ private Mapping defaultMapping;
- /**
- * Inner class eventhandler, forward the Castor SAX events
- * to Cocoon 2 Events
- */
- CastorEventAdapter = new HandlerBase(){
- public void startElement(String name, AttributeList attributes) throws
SAXException
- {
- AttributesImpl a= new AttributesImpl();
- for(int i=0;i <attributes.getLength(); i++){
- a.addAttribute("",attributes.getName(i),attributes.getName(i),
- "",attributes.getValue(i));
- }
+ private boolean in_castor_element = false;
- CastorTransformer.super.contentHandler.startElement("",name,name,a);
- }
- public void characters(char[] chars, int offset, int length) throws
SAXException
- {
- CastorTransformer.super.contentHandler.characters(chars, offset,
length);
- }
+ public void configure(Configuration conf) throws ConfigurationException {
+ this.defaultMappingName = conf.getChild(ATTRIB_MAPPING).getValue();
+ }
- public void endElement(String name) throws SAXException
- {
+ public void setup(SourceResolver resolver, Map objectModel, String src,
Parameters params)
+ throws ProcessingException, SAXException, IOException {
+ this.objectModel = objectModel;
+ this.resolver = resolver;
- CastorTransformer.super.contentHandler.endElement("", name,name);
+ if (defaultMappingName != null) {
+ try {
+ defaultMapping = loadMapping(defaultMappingName);
+ } catch (Exception e) {
+ getLogger().warn("Unable to load mapping " + defaultMappingName, e);
}
- };
- }
-
- public void setup(SourceResolver resolver, Map objectModel, String src,
Parameters params) throws org.apache.cocoon.ProcessingException,
org.xml.sax.SAXException, java.io.IOException {
- this.objectModel=objectModel;
- this.resolver=resolver;
+ }
}
- public void endElement(String uri, String name, String raw) throws
org.xml.sax.SAXException {
- if(CASTOR_URI.equals(uri)){
- in_castor_element= false;
- return;
+ public void endElement(String uri, String name, String raw) throws SAXException
{
+ if (CASTOR_URI.equals(uri)) {
+ in_castor_element = false;
+ } else {
+ super.endElement(uri, name, raw);
}
-
- super.endElement( uri, name, raw);
}
- public void startElement(String uri, String name, String raw, Attributes attr)
throws org.xml.sax.SAXException {
- if(CASTOR_URI.equals(uri)){
+ public void startElement(String uri, String name, String raw, Attributes attr)
throws SAXException {
+ if (CASTOR_URI.equals(uri)) {
in_castor_element= true;
-
- process(name,attr);
- return;
+ process (name, attr);
+ } else {
+ super.startElement(uri, name, raw, attr);
}
- super.startElement( uri, name, raw, attr);
}
- public void characters(char[] ch, int start, int len) throws
org.xml.sax.SAXException {
- if(in_castor_element)
- return;
- super.characters(ch,start, len);
+ public void characters(char[] ch, int start, int len) throws SAXException {
+ if (!in_castor_element) {
+ super.characters(ch,start, len);
+ }
}
- private void process(String command,Attributes attr){
-
- if(command.equals(CMD_INSERT_BEAN)) {
- String sourcemap = attr.getValue(ATTRIB_SCOPE);
- String name = attr.getValue(ATTRIB_NAME);
- String mapping = attr.getValue("mapping");
- Object toInsert;
+ private void process (String command, Attributes attr) throws SAXException {
+ if (CMD_INSERT_BEAN.equals(command)) {
+ final String scope = attr.getValue(ATTRIB_SCOPE);
+ final String name = attr.getValue(ATTRIB_NAME);
+ final String mapping = attr.getValue(ATTRIB_MAPPING);
+ if (name == null){
+ throw new SAXException("Required attribute name is missing on
element " + CMD_INSERT_BEAN);
+ }
Request request = ObjectModelHelper.getRequest(objectModel);
- if(name == null){
- getLogger().error("attribut to insert not set");
- }
- /*
- searcl all maps for the given bean
- */
- else{
- if( sourcemap == null || VALUE_SITEMAP.equals(sourcemap)){
- //System.out.println("Searching bean " + name+ " in
"+VALUE_SITEMAP);
- toInsert=objectModel.get(name);
- if(toInsert != null){
- insertBean(toInsert,mapping);
- return;
+ Object bean = null;
+ if (scope == null) {
+ // Search for bean in (1) objectModel, (2) request, (3) session,
and (4) context.
+ bean = request.getAttribute(name);
+ if (bean == null) {
+ Session session = request.getSession(false);
+ if (session != null) {
+ bean = session.getAttribute(name);
}
}
- if( sourcemap == null || VALUE_REQUEST.equals(sourcemap)){
- //System.out.println("Searching bean " + name+ " in "+
VALUE_REQUEST);
- toInsert=request.getAttribute(name);
- if(toInsert != null){
- insertBean(toInsert,mapping);
- return;
+ if (bean == null) {
+ Context context = ObjectModelHelper.getContext(objectModel);
+ if (context != null) {
+ bean = context.getAttribute(name);
}
}
- if(sourcemap == null || VALUE_SESSION.equals(sourcemap)){
- //System.out.println("Searching bean " + name+ " in
"+VALUE_SESSION);
-
- Session session =request.getSession(false);
- if(session != null){
- toInsert=session.getAttribute(name);
- if(toInsert != null){
- insertBean(toInsert,mapping);
- return;
- }
- }
+ if (bean == null) {
+ bean = objectModel.get(name);
}
- if(sourcemap == null || VALUE_CONTEXT.equals(sourcemap)){
- Context context = ObjectModelHelper.getContext(objectModel);
- if(context != null){
- toInsert=context.getAttribute(name);
- if(toInsert != null){
- insertBean(toInsert,mapping);
- return;
- }
- }
+ } else if (SCOPE_SITEMAP.equals(scope)) {
+ bean = objectModel.get(name);
+ } else if (SCOPE_REQUEST.equals(scope)) {
+ bean = request.getAttribute(name);
+ } if (SCOPE_SESSION.equals(scope)) {
+ Session session = request.getSession(false);
+ if (session != null) {
+ bean = session.getAttribute(name);
+ }
+ } if (SCOPE_CONTEXT.equals(scope)) {
+ Context context = ObjectModelHelper.getContext(objectModel);
+ if(context != null){
+ bean=context.getAttribute(name);
}
}
- getLogger().debug("Bean " +name + " could not be found");
- return;
- } // end CMD_INSERT_BEAN
- getLogger().error("Unknown command: " +command);
- }
- private void insertBean(Object bean,String mappingpath){
- if(bean == null){
- getLogger().debug ("no bean found");
- return;
- }
- try{
- Mapping mapping;
- if(mappingpath != null){
- mapping=mappingLoader(mappingpath);
+ if (bean != null) {
+ insertBean(name, bean, mapping);
} else {
- mapping=mappingLoader(defaultmapping);
+ getLogger().warn("Bean " +name + " could not be found");
}
-
- Marshaller marshaller= new Marshaller(CastorEventAdapter);
- marshaller.setMapping(mapping);
- marshaller.marshal(bean);
- } catch(Exception e){
- e.printStackTrace();
+ } else {
+ throw new SAXException("Unknown command: " + command);
}
}
- private Mapping mappingLoader(String path) throws MappingException,IOException{
+ private void insertBean (String name, Object bean, String map) throws
SAXException {
+ try {
+ Marshaller marshaller = new Marshaller(new
IncludeXMLConsumer(super.contentHandler));
+ try {
+ Mapping mapping = null;
+ if (map != null) {
+ mapping = loadMapping(map);
+ } else {
+ mapping = defaultMapping;
+ }
+ marshaller.setMapping(mapping);
+ } catch (Exception e) {
+ getLogger().warn("Unable to load mapping " + map, e);
+ }
- if(mappingCache == null){
- mappingCache= new HashMap();
- }
- // cache already exsit
- else{
- // and contain the mapping already
- if(mappingCache.containsKey(path)){
- return (Mapping)mappingCache.get(path);
+ if (bean instanceof Collection) {
+ Iterator i = ((Collection)bean).iterator();
+ while (i.hasNext()) {
+ marshaller.marshal(i.next());
+ }
+ } else {
+ marshaller.marshal(bean);
}
+ } catch (Exception e) {
+ getLogger().warn("Failed to marshal bean " + name, e);
}
- // mapping not found in cache or the cache is new
- Mapping mapping = new Mapping();
- mapping.loadMapping(getFile(resolver,path));
- mappingCache.put(path,mapping);
- return mapping;
-
}
- public String getFile(SourceResolver sr, String FileName) {
- try{
- String path = sr.resolveURI(FileName).getURI();
- if(path.startsWith(FILE_PREFIX)){
- path = path.substring(FILE_PREFIX.length());
+ private Mapping loadMapping (String file) throws MappingException, IOException {
+ synchronized (CastorTransformer.class) {
+ // Create cache (once) if does not exist
+ if (mappings == null) {
+ mappings = new HashMap();
}
- return path;
- }
- catch(Exception e){
- getLogger().error("could not read mapping file",e);
- return null;
- }
- }
+ Mapping mapping;
+ Source source = resolver.resolveURI(file);
+ try {
+ mapping = (Mapping) mappings.get(source.getURI());
+ if (mapping == null) {
+ // mapping not found in cache or the cache is new
+ mapping = new Mapping();
+ InputSource in = new InputSource(source.getInputStream());
+ mapping.loadMapping(in);
+ mappings.put (source.getURI(), mapping);
+ }
+ } finally {
+ resolver.release(source);
+ }
- public void configure(Configuration conf) throws ConfigurationException {
- this.defaultmapping = conf.getChild(MAPPING_CONFIG).getValue();
+ return mapping;
+ }
}
}
1.2 +3 -1 xml-cocoon2/lib/local/local-libs.txt
Index: local-libs.txt
===================================================================
RCS file: /home/cvs/xml-cocoon2/lib/local/local-libs.txt,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- local-libs.txt 24 May 2002 09:30:45 -0000 1.1
+++ local-libs.txt 2 Feb 2003 03:26:47 -0000 1.2
@@ -1,3 +1,5 @@
Put here local libraries required for optional components, such as JFor or JavaMail.
-Local libraries aren't checked by the jar-checking system, so you must ensure they
do not conflict with libraries that are part of the Cocoon distribution (directories
core/ and optional/).
\ No newline at end of file
+Local libraries aren't checked by the jar-checking system, so you must ensure they
do
+not conflict with libraries that are part of the Cocoon distribution (directories
core/
+and optional/).
\ No newline at end of file
1.1 xml-cocoon2/lib/optional/castor-0.9.4.2-xml.jar
<<Binary file>>
----------------------------------------------------------------------
In case of troubles, e-mail: [EMAIL PROTECTED]
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]