/** * Copyright (c) 2009 Juwi MacMillan Group GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.juwimm.cms.cocoon.transformation; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.sax.SAXResult; import org.apache.avalon.excalibur.pool.Recyclable; import org.apache.avalon.framework.parameters.Parameters; import org.apache.cocoon.ProcessingException; import org.apache.cocoon.environment.SourceResolver; import org.apache.cocoon.transformation.AbstractTransformer; import org.apache.log4j.Logger; import org.tizzit.util.XercesHelper; import org.tizzit.util.xml.SAXHelper; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; import de.juwimm.cms.beans.WebServiceSpring; import de.juwimm.cms.cocoon.helper.CocoonSpringHelper; import de.juwimm.cms.vo.UnitValue; import de.juwimm.cms.vo.ViewDocumentValue; /** * Transformer parses input for the tag "unit" and fetches and appends unitpath, unitname and image-information</br> * * <p><h5>Configuration:</h5> * <pre> * <map:transformer name="unit" src="de.juwimm.cms.cocoon.transformation.UnitTransformer"/> * </pre> * </p> * <p><h5>Usage:</h5> * Just put code like this in your pipeline: * <pre> * <map:transform type="unit"/> * </pre> * </p> * <p>The input must be something like this:</br> * <pre><unit id="58" siteId=6"/></pre></br> * </p> * <p><h5>Result:</h5> * The output will look like this:</br> * <pre> * <unit id="58" siteId="6" logoId="614" imageId="727"> * <unitname><![CDATA[Confidential]]></unitname> * <lastModified><![CDATA[17.01.2008 19:31:50]]></lastModified> * <unitImage> * <image height="1126" id="727" mimeType="image/jpeg" width="902"> * <fileName><![CDATA[virgil.jpg]]></fileName> * <altText><![CDATA[alt. Text]]></altText> * <timeStamp><![CDATA[21.06.2007 18:12:32]]></timeStamp> * </image> * </unitImage> * <unitLogo> * <image height="412" id="614" mimeType="image/jpeg" width="914"> * <fileName><![CDATA[tuev.jpeg]]></fileName> * <altText/> * <timeStamp><![CDATA[14.06.2007 11:19:27]]></timeStamp> * </image> * </unitLogo> * <languagePath url="Confidential" language="deutsch" viewType="browser" viewDocumentId="18"/> * </unit> * </pre> * </p> * <p> * Additional attributes in the "unit"-tag are kept, like the attribute "siteId" in the example above. * </p> * <p> * A special feature of this transformer is, that you can parameterize for every "unit"-tag, how much information you like to get.<br/> * You can skip the transformation of a unit by adding the attribute "disableParsing" with the value "true".<br/> * If you set the attribute "disableUrlResolve" with the value "true" the most expansive search for information is skipped.<br/> * If you set the attribute "disableUrlResolve" with the value "false" you get the element "languagePath" with the following information:<br/> * <ul> * <li>url - the path to this unit</li> * <li>language - the language for this unit</li> * <li>viewType - the viewType for this unit</li> * <li>viewDocumentId - the id for this viewDocument</li> * </ul> * </p> * <p> * If you like to get all available languages for a page or unit, please look at * @see de.juwimm.cms.cocoon.transformation.LanguageTransformer * </p> * * @author <a href="carsten.schalm@juwimm.com">Carsten Schalm</a> * Juwi|MacMillan Group Gmbh, Walsrode, Germany * @version $Id$ * @since ConQuest 2.0 */ public class UnitTransformer extends AbstractTransformer implements Recyclable { private static Logger log = Logger.getLogger(UnitTransformer.class); private WebServiceSpring webSpringBean = null; private HashMap<Integer, ArrayList> vdId4SitesCache = new HashMap<Integer, ArrayList>(); /* (non-Javadoc) * @see org.apache.cocoon.sitemap.SitemapModelComponent#setup( * org.apache.cocoon.environment.SourceResolver, java.util.Map, java.lang.String, org.apache.avalon.framework.parameters.Parameters) */ public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par) throws ProcessingException, SAXException, IOException { try { this.webSpringBean = (WebServiceSpring) CocoonSpringHelper.getBean(objectModel, CocoonSpringHelper.WEB_SERVICE_SPRING); } catch (Exception exf) { log.error("Could not load webservicespringbean!", exf); } } /* * (non-Javadoc) * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes) */ @Override public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException { if (localName.equals("unit")) { boolean disableParsing = Boolean.valueOf(attrs.getValue("disableParsing")).booleanValue(); if (!disableParsing) { AttributesImpl newAttr = new AttributesImpl(attrs); String unitName = null; Integer logoId = null; Integer imageId = null; Integer unitId = new Integer(attrs.getValue("id")); if (unitId == null) { log.error("UnitId not found!"); super.contentHandler.startElement(uri, localName, qName, attrs); } else { try { UnitValue unitValue = this.webSpringBean.getUnit(unitId); if (unitValue == null) { log.error("Unit with id " + unitId.toString() + " not found!"); super.contentHandler.startElement(uri, localName, qName, attrs); } else { try { logoId = unitValue.getLogoId(); SAXHelper.setSAXAttr(newAttr, "logoId", logoId.toString()); } catch (Exception exe) { if (log.isDebugEnabled()) log.debug("Error getting unit-logo: " + exe.getMessage()); } try { imageId = unitValue.getImageId(); SAXHelper.setSAXAttr(newAttr, "imageId", imageId.toString()); } catch (Exception exe) { if (log.isDebugEnabled()) log.debug("Error getting unit-image: " + exe.getMessage()); } unitName = unitValue.getName(); if (log.isDebugEnabled()) log.debug("current Unit: " + unitName); super.contentHandler.startElement(uri, localName, qName, newAttr); this.convertUnitInfoToSax(unitId); boolean disableUrlResolve = Boolean.valueOf(attrs.getValue("disableUrlResolve")).booleanValue(); if (!disableUrlResolve) { Integer siteId = null; try { siteId = this.webSpringBean.getSite4Unit(unitId).getSiteId(); } catch (Exception e) { if (log.isDebugEnabled()) log.debug("Error getting site for unit " + unitId.toString() + ": " + e.getMessage()); } if (siteId == null) { log.error("Site not found!"); } else { Iterator vdIterator = getVdId4Site(siteId).iterator(); while (vdIterator.hasNext()) { ViewDocumentValue viewDocumentValue = (ViewDocumentValue) vdIterator.next(); if (log.isDebugEnabled()) log.debug("current viewDocument: " + viewDocumentValue.toString()); AttributesImpl vdAttr = new AttributesImpl(); String unitPath = null; String language = null; String viewType = null; try { unitPath = this.webSpringBean.getPath4Unit(unitId, viewDocumentValue.getViewDocumentId()); } catch (Exception exe) { if (log.isDebugEnabled()) log.debug("Error getting unit-path: " + exe.getMessage()); } // id unitPath is null this unit has no page associated in this language-version if (unitPath != null) { try { language = viewDocumentValue.getLanguage(); } catch (Exception exe) { if (log.isDebugEnabled()) log.debug("Error getting unit-language: " + exe.getMessage()); } try { viewType = viewDocumentValue.getViewType(); } catch (Exception exe) { if (log.isDebugEnabled()) log.debug("Error getting unit-viewType: " + exe.getMessage()); } SAXHelper.setSAXAttr(vdAttr, "url", unitPath); if (language != null) SAXHelper.setSAXAttr(vdAttr, "language", language); if (viewType != null) SAXHelper.setSAXAttr(vdAttr, "viewType", viewType); SAXHelper.setSAXAttr(vdAttr, "viewDocumentId", viewDocumentValue.getViewDocumentId().toString()); super.contentHandler.startElement(uri, "languagePath", "languagePath", vdAttr); super.contentHandler.endElement(uri, "languagePath", "languagePath"); } } } } } } catch (Exception exe) { if (log.isDebugEnabled()) log.debug("Error: " + exe.getMessage()); } } } else { super.contentHandler.startElement(uri, localName, qName, attrs); } } else { super.contentHandler.startElement(uri, localName, qName, attrs); } } @Override public void recycle() { if (log.isDebugEnabled()) log.debug("begin recycle"); this.vdId4SitesCache = null; } private ArrayList getVdId4Site(Integer siteId) { if (this.vdId4SitesCache == null) this.vdId4SitesCache = new HashMap<Integer, ArrayList>(); if (this.vdId4SitesCache.containsKey(siteId)) { return this.vdId4SitesCache.get(siteId); } ArrayList<ViewDocumentValue> vdList = new ArrayList<ViewDocumentValue>(); ViewDocumentValue[] viewDocuments = null; try { viewDocuments = this.webSpringBean.getViewDocuments4Site(siteId); } catch (Exception e) { log.error("Error getting viewDocuments for site " + siteId.toString() + ": " + e.getMessage()); } if (viewDocuments != null) { for (int i = 0; i < viewDocuments.length; i++) { vdList.add(viewDocuments[i]); } } this.vdId4SitesCache.put(siteId, vdList); return (vdList); } private void convertUnitInfoToSax(Integer unitId) { try { SAXResult result = new SAXResult(super.contentHandler); String unitInfo = this.webSpringBean.getUnitInfoXml(unitId); Node ndeUnitInfo = XercesHelper.string2Dom(unitInfo).getDocumentElement(); NodeList children = ndeUnitInfo.getChildNodes(); TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer xform = transformerFactory.newTransformer(); DOMSource source = new DOMSource(); for (int i = 0; i < children.getLength(); i++) { source.setNode(children.item(i)); xform.transform(source, result); } } catch (Exception e) { log.warn("Error: " + e.getMessage(), e); } } }