Package org.apache.cocoon.transformation

Source Code of org.apache.cocoon.transformation.CastorTransformer

package org.apache.cocoon.transformation;

import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.parameters.Parameters;

import org.apache.cocoon.environment.Context;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.Session;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.environment.ObjectModelHelper;

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.xml.sax.Attributes;
import org.xml.sax.HandlerBase;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
* Description: 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
* default mapping. This mapping is used as long as no other mapping
* is spezfied as the element
*
*<pre>
*  &ltmap:transformer name="CastorTransformer" src="org.apache.cocoon.transformation.CastorTransformer"&gt
*    &ltmapping&gtcastor/xmapping.xml&lt/mapping&gt
*  &lt/map:transformer&gt
*</pre>
*
* A sample for the use:
* <pre>
*   &ltroot xmlns:castor="http://castor.exolab.org/cocoontransfomer"&gt
*  &ltcastor:InsertBean name="invoice"/&gt
*  &ltcastor:InsertBean name="product" scope="sitemap" mapping="castor/specicalmapping.xml"/&gt
*  &lt/root&gt
* </pre>
* The CastorTransfomer support only one Element <code>castor:InsertBean</code>. This
* element is replaced with the marshalled object. The Object given through the
* attrbute <code>name</code> will be searched in the <code>sitemap, request,
* session</code> and at least in <code>application</code>
* If the scope is explicitly given, e.g , the object will ge located only here
* The Attribut <code>mapping</code> specifys the mapping to be used. If not given
* the default mapping is used
* <pre/>
* Author <a href="mailto:mauch@imkenberg.de">Thorsten Mauch</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";

    final static String MAPPING_CONFIG ="mapping";
    private final static String FILE_PREFIX="file:";

    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() {

    /**
     * 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));
          }

          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 endElement(String name) throws SAXException
  {

          CastorTransformer.super.contentHandler.endElement("", name,name);
  }
    };
  }


  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;


    }

    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)){
        in_castor_element= true;

        process(name,attr);
        return;
    }
    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);

  }

  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;

        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;
            }
          }
          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(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(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;
              }
            }
          }
        }
        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);
      }
      else{
         mapping=mappingLoader(defaultmapping);
      }



      Marshaller marshaller= new Marshaller(CastorEventAdapter);
      marshaller.setMapping(mapping);
      marshaller.marshal(bean);
    }
    catch(Exception e){
      e.printStackTrace();
    }
  }

  private Mapping mappingLoader(String path) throws MappingException,IOException{

    if(mappingCache == null){
      mappingCache= new HashMap();
    }
    // cache already exsit
    else{
      // and contain the mapping already
      if(mappingCache.containsKey(path)){
          return (Mapping)mappingCache.get(path);
      }
    }
    // 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.resolve(FileName).getSystemId();
    if(path.startsWith(FILE_PREFIX)){
       path = path.substring(FILE_PREFIX.length());
    }
    return path;

    }
    catch(Exception e){
       getLogger().error("could not read mapping file",e);
      return null;
    }
  }
  public void configure(Configuration conf) throws org.apache.avalon.framework.configuration.ConfigurationException {
    try{
      defaultmapping=conf.getChild(MAPPING_CONFIG).getValue();
    }
    catch(Exception e){
      e.printStackTrace();
      getLogger().error("can't load default mapping",e);
    }
  }
}
TOP

Related Classes of org.apache.cocoon.transformation.CastorTransformer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.