package org.greenstone.gsdl3.core; import org.greenstone.gsdl3.util.*; import org.greenstone.gsdl3.action.*; // XML classes import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.Document; import org.w3c.dom.Element; // other java classes import java.io.File; import java.util.HashMap; import java.util.Enumeration; /** A receptionist that uses xslt to transform the page_data before returning it. . Receives requests consisting * of an xml representation of cgi args, and returns the page of data - in * html by default. The requests are processed by the appropriate action class * * @see Action */ public class TransformingReceptionist extends Receptionist{ /** the list of xslt to use for actions */ protected HashMap xslt_map = null; /** a transformer class to transform xml using xslt */ protected XMLTransformer transformer=null; public TransformingReceptionist() { super(); this.xslt_map = new HashMap(); this.transformer = new XMLTransformer(); } /** configures the receptionist - overwrite this to set up the xslt map*/ public boolean configure() { if (this.config_params==null) { System.err.println("Receptionist Error: config variables must be set before calling configure"); return false; } if (this.mr==null) { System.err.println("Receptionist Error: message router must be set before calling configure"); return false; } // find the config file containing a list of actions File interface_config_file = new File(GSFile.interfaceConfigFile(GSFile.interfaceHome((String)this.config_params.get(GSConstants.GSDL3_HOME), (String)this.config_params.get(GSConstants.INTERFACE_NAME)))); if (!interface_config_file.exists()) { System.err.println("TransformingReceptionist: interface config file: "+interface_config_file.getPath()+" not found!"); return false; } Element config_doc = this.converter.getDOM(interface_config_file).getDocumentElement(); Element action_list = (Element)GSXML.getChildByTagName(config_doc, GSXML.ACTION_ELEM+GSXML.LIST_MODIFIER); NodeList actions = action_list.getElementsByTagName(GSXML.ACTION_ELEM); for (int i=0; i"+subxslt); this.xslt_map.put(map_key, subxslt); } } return true; } protected Element postProcessPage(Element page) { // might need to add some data to the page addExtraInfo(page); // transform the page using xslt Element transformed_page = transformPage(page); return transformed_page; } /** overwrite this to add any extra info that might be needed in the page before transformation */ protected void addExtraInfo(Element page) {} /** transform the page using xslt * we need to get any format element out of the page and add it to the xslt * before transforming */ protected Element transformPage(Element page) { Element request = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_REQUEST_ELEM); String action = request.getAttribute("action"); String subaction = request.getAttribute("subaction"); Element cgi_param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER); String collection = ""; if (cgi_param_list != null) { HashMap params = GSXML.extractParams(cgi_param_list, false); collection = (String)params.get(GSCGI.COLLECTION_ARG); if (collection == null) collection = ""; } String xslt_file = getXSLTFileName(action, subaction, collection); if (xslt_file==null) { // cant transform the page - return null or the original? System.err.println(" cant find the xslt file needed, so returning the original page!"); return page; } Document style_doc = this.converter.getDOM(new File(xslt_file)); // look for the format element in the page response Element page_response = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_RESPONSE_ELEM); Element format_elem = (Element)GSXML.getChildByTagName(page_response, GSXML.FORMAT_ELEM); if (format_elem != null) { page_response.removeChild(format_elem); // need to transform the format info String stylesheet_file = GSFile.stylesheetFile((String)this.config_params.get(GSConstants.GSDL3_HOME), (String)this.config_params.get(GSConstants.SITE_NAME), (String)this.config_params.get(GSConstants.INTERFACE_NAME), "", "config_format.xsl"); Document stylesheet = this.converter.getDOM(new File(stylesheet_file)); Document format_doc = this.converter.newDOM(); format_doc.appendChild(format_doc.importNode(format_elem, true)); Element new_format = (Element)this.transformer.transform(stylesheet, format_doc); // add it in to the main stylesheet GSXSLT.mergeStylesheets(style_doc, new_format); ///ystem.out.println("the converted stylesheet is:"); ///ystem.out.println(this.converter.getPrettyString(style_doc.getDocumentElement())); } // there is a thing called a URIResolver which you can set for a transformer or transformer factory. may be able to use this instead of this absoluteIncludepaths hack GSXSLT.absoluteIncludePaths(style_doc, (String)this.config_params.get(GSConstants.GSDL3_HOME), (String)this.config_params.get(GSConstants.SITE_NAME), (String)this.config_params.get(GSConstants.INTERFACE_NAME), collection); // put the page into a document - this is necessary for xslt to get the paths right if you have paths relative to the document root eg /page. Document doc = this.converter.newDOM(); doc.appendChild(doc.importNode(page, true)); return (Element)this.transformer.transform(style_doc, doc, config_params); } protected String getXSLTFileName(String action, String subaction, String collection) { String name = null; if (!subaction.equals("")) { String key = action+":"+subaction; name = (String) this.xslt_map.get(key); } // try the action by itself if (name==null) { name = (String) this.xslt_map.get(action); } // now find the absolute path String stylesheet = GSFile.stylesheetFile((String)this.config_params.get(GSConstants.GSDL3_HOME), (String)this.config_params.get(GSConstants.SITE_NAME), (String)this.config_params.get(GSConstants.INTERFACE_NAME), collection, name); if (stylesheet==null) { System.out.println("cant find stylesheet for "+name); } return stylesheet; } }