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]