package com.idega.builder.facelets; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.StringReader; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.jdom.Attribute; import org.jdom.Document; import org.jdom.Element; import org.jdom.Namespace; import org.jdom.Text; import org.jdom.output.Format; import org.jdom.output.XMLOutputter; import org.w3c.tidy.Configuration; import org.w3c.tidy.Tidy; import com.idega.builder.business.BuilderLogic; import com.idega.builder.business.CachedBuilderPage; import com.idega.util.CoreConstants; import com.idega.util.FileUtil; import com.idega.util.StringHandler; import com.idega.xml.XMLDocument; import com.idega.xml.XMLParser; /** * <p> * Class to convert IBXML and HTML to the new Facelet formats. * </p> * * @author <a href="tryggvi@idega.is">Tryggvi Larusson </a> * * Last modified: $Date: 2009/01/14 15:35:25 $ by $Author: tryggvil $ * @version $Id: BuilderFaceletConverter.java,v 1.2 2009/01/14 15:35:25 tryggvil Exp $ */ public class BuilderFaceletConverter { //private String pageKey; private String formatTo = BuilderLogic.PAGE_FORMAT_FACELET; private String formatFrom = BuilderLogic.PAGE_FORMAT_IBXML; public String getFormatTo() { return formatTo; } public void setFormatTo(String formatTo) { this.formatTo = formatTo; if(isLegacyConvert()){ //We'll switch to a namespace without a prefix: this.builderNamespace=Namespace.getNamespace(sBuilderNamespace); this.htmlNamespace=Namespace.getNamespace("html",sHtmlNamespace); } } public String getFormatFrom() { return formatFrom; } public void setFormatFrom(String formatFrom) { this.formatFrom = formatFrom; } private String stringSourceMarkup; private XMLParser parser; boolean legacyConvert = false; public static final String sBuilderNamespace = "http://xmlns.idega.com/com.idega.builder"; public Namespace builderNamespace = Namespace.getNamespace("b", sBuilderNamespace); public static final String sFaceletNamespace = "http://java.sun.com/jsf/facelets"; public Namespace faceletNamespace = Namespace .getNamespace("ui", sFaceletNamespace); public static final String sHtmlNamespace = "http://www.w3.org/1999/xhtml"; public Namespace htmlNamespace = Namespace.getNamespace(sHtmlNamespace); private CachedBuilderPage page; public BuilderFaceletConverter(CachedBuilderPage page, String pageFormatTo, String stringSourceMarkup) { this.page = page; setFormatTo(pageFormatTo); setFormatFrom(page.getPageFormat()); this.stringSourceMarkup = stringSourceMarkup; } public BuilderFaceletConverter(String pageFormatFrom, String pageFormatTo, String stringSourceMarkup) { setFormatTo(pageFormatTo); setFormatFrom(pageFormatFrom); this.stringSourceMarkup = stringSourceMarkup; } public BuilderFaceletConverter(CachedBuilderPage cPage, String pageFormatTo) { this(cPage,pageFormatTo,cPage.toString()); } public void convert() throws Exception { this.parser = new XMLParser(false); // XMLDocument doc = page.getXMLDocument(); Document faceletDoc = new Document(); // DocType faceletDocType = // faceletDoc.setDocType(docType) XMLDocument doc = parser .parse(new StringReader(this.stringSourceMarkup)); Object o = doc.getDocument(); if (o instanceof Document) { Document d = (Document) o; try { Element ibXmlRoot = d.getRootElement(); if (getFormatFrom().equals(BuilderLogic.PAGE_FORMAT_IBXML)) { if (ibXmlRoot.getName().equals("xml")) { // ignore the xml top element and go to the page // element: Element pageElement = ibXmlRoot.getChild("page"); Element newPageElement = null; Element newRootElement = null; if (isLegacyConvert()) { //newRootElement = new Element("page",builderNamespace); newRootElement = new Element("xml", builderNamespace); newPageElement = new Element("page", builderNamespace); newRootElement.addContent(newPageElement); } else { newRootElement = new Element("html", htmlNamespace); newPageElement = new Element("composition", faceletNamespace); newRootElement.addContent(newPageElement); } faceletDoc.setRootElement(newRootElement); transformElementToFacelet(pageElement, newPageElement); XMLOutputter out = new XMLOutputter(); out.setFormat(Format.getPrettyFormat()); this.stringSourceMarkup = out.outputString(faceletDoc); } } else if (getFormatFrom().equals(BuilderLogic.PAGE_FORMAT_HTML)) { String text = this.stringSourceMarkup; // Use JTidy to clean up the HTML Tidy tidy = new Tidy(); tidy.setXHTML(true); tidy.setXmlOut(true); tidy.setShowWarnings(false); tidy.setCharEncoding(Configuration.UTF8); InputStream stream = null; ByteArrayOutputStream baos = null; try { stream = StringHandler.getStreamFromString(text); baos = new ByteArrayOutputStream(); tidy.parse(stream, baos); text = baos.toString(CoreConstants.ENCODING_UTF8); text = text.replaceAll("html xmlns=\"http://www.w3.org/1999/xhtml\"", "html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:ui=\"http://java.sun.com/jsf/facelets\""); text = rewriteRegionTags(text); this.stringSourceMarkup = text; } catch (Exception e) { e.printStackTrace(); } finally { // closeInputStream(stream); // closeOutputStream(baos); stream.close(); baos.close(); } // if (StringUtil.isEmpty(text)) { // return toPrettify; // } // text = removeAbsoluteReferences(text); // return getOnlyBodyContent(text); } else { // not old style IBXML, exiting without change } } catch (Exception e) { e.printStackTrace(); // return false; } } } private String rewriteRegionTags(String source) { // Process the template regions: String[] parts = source.split("<!-- TemplateBeginEditable"); String newString = parts[0]; for (int i = 1; i < parts.length; i++) { String part = parts[i]; String[] t = part.split("TemplateEndEditable -->"); String toParse = t[0]; String[] a1 = toParse.split("name=\""); String[] a2 = a1[1].split("\""); String regionId = a2[0]; String newRegionCode = "<ui:insert name=\"" + regionId + "\"/>"; newString += newRegionCode; // int childNumber = Integer.parseInt(t[0]) - 1; /* * try{ UIComponent region = getRegion(regionId); * renderChild(ctx,region); } catch(ClassCastException cce){ * cce.printStackTrace(); } * * out.write(t[1]); */ newString += t[1]; } return newString; } private void transformElementToFacelet(Element oldElement, Element newElement) { // String text = oldElement.getText(); // if(text!=null){ // newElement.setText(text); // } List attributes = oldElement.getAttributes(); for (Iterator iterator = attributes.iterator(); iterator.hasNext();) { Attribute attribute = (Attribute) iterator.next(); String name = attribute.getName(); String value = attribute.getValue(); if (oldElement.getName().equals("page") && name.equals("template")&&!isLegacyConvert()) { value = FaceletsUtil.getRewrittenTemplateReference(this.page,value); Attribute newAttribute = new Attribute(name, value); newElement.setAttribute(newAttribute); } else if (oldElement.getName().equals("page") && !isLegacyConvert()) { // Not add the attributes to the composition element } else if (oldElement.getName().equals("region") && !isLegacyConvert()) { // Not add the attributes to the composition element other than // the name attribute: if (name.equals("id")) { Attribute newAttribute = new Attribute("name", value); newElement.setAttribute(newAttribute); } } else { Attribute newAttribute = new Attribute(name, value); newElement.setAttribute(newAttribute); } } List children = oldElement.getContent(); for (Iterator iterator = children.iterator(); iterator.hasNext();) { Object child = iterator.next(); if (child instanceof Element) { Element childElement = (Element) child; Element newChildElement = null; if (childElement.getName().equals("region") && !isLegacyConvert()) { newChildElement = new Element("define", faceletNamespace); newElement.addContent(newChildElement); } else { newChildElement = new Element(childElement.getName(), builderNamespace); newElement.addContent(newChildElement); } if (childElement.getName().equals("property")&&!isLegacyConvert()) { List nameChildren = getChildren(childElement, "name"); List valueChildren = getChildren(childElement, "value"); if (nameChildren.size() == 1) { Element nameChild = (Element) nameChildren.get(0); Element valueChild = (Element) valueChildren.get(0); Attribute newNameAttribute = new Attribute("name", sBuilderNamespace); newNameAttribute.setValue(nameChild.getText()); newChildElement.setAttribute(newNameAttribute); Attribute newValueAttribute = new Attribute("value", sBuilderNamespace); newValueAttribute.setValue(valueChild.getText()); newChildElement.setAttribute(newValueAttribute); } else { transformElementToFacelet(childElement, newChildElement); } } else { transformElementToFacelet(childElement, newChildElement); } } else if (child instanceof Text) { Text childElement = (Text) child; Text newChildElement = new Text(childElement.getText()); newElement.addContent(newChildElement); } } } private List getChildren(Element oldElement, String name) { ArrayList list = new ArrayList(); List children = oldElement.getContent(); for (Iterator iterator = children.iterator(); iterator.hasNext();) { Object child = iterator.next(); if (child instanceof Element) { Element element = (Element) child; if (element.getName().equals(name)) { list.add(element); } } } return list; } public String getConvertedMarkupString() { // TODO Auto-generated method stub return stringSourceMarkup; } public static void main(String args[]) throws Exception { // InputStreamReader sourceInput = new InputStreamReader(new // FileInputStream(new File("/Users/tryggvil/builderpage.ibxml"))); String source = FileUtil .getStringFromFile("/Users/tryggvil/builderpage.ibxml"); BuilderFaceletConverter converter = new BuilderFaceletConverter(BuilderLogic.PAGE_FORMAT_IBXML, BuilderLogic.PAGE_FORMAT_FACELET, source); //String source = FileUtil // .getStringFromFile("/Users/tryggvil/testhtml.html"); //BuilderFaceletConverter converter = new BuilderFaceletConverter(BuilderLogic.PAGE_FORMAT_HTML, // BuilderLogic.PAGE_FORMAT_IBXML, source); converter.convert(); String output = converter.getConvertedMarkupString(); System.out.println("Converted to:\n\n" + output); } public boolean isLegacyConvert() { //return legacyConvert; if(getFormatTo().equals(BuilderLogic.PAGE_FORMAT_IBXML2)){ return true; } else{ return false; } } //public void setLegacyConvert(boolean legacyConvert) { // this.legacyConvert = legacyConvert; //} }